super-smart-mod 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/pry-0.16.0/CHANGELOG.md +1211 -0
  3. data/pry-0.16.0/LICENSE +25 -0
  4. data/pry-0.16.0/README.md +469 -0
  5. data/pry-0.16.0/bin/pry +13 -0
  6. data/pry-0.16.0/lib/pry/basic_object.rb +10 -0
  7. data/pry-0.16.0/lib/pry/block_command.rb +22 -0
  8. data/pry-0.16.0/lib/pry/class_command.rb +194 -0
  9. data/pry-0.16.0/lib/pry/cli.rb +211 -0
  10. data/pry-0.16.0/lib/pry/code/code_file.rb +114 -0
  11. data/pry-0.16.0/lib/pry/code/code_range.rb +73 -0
  12. data/pry-0.16.0/lib/pry/code/loc.rb +105 -0
  13. data/pry-0.16.0/lib/pry/code.rb +357 -0
  14. data/pry-0.16.0/lib/pry/code_object.rb +197 -0
  15. data/pry-0.16.0/lib/pry/color_printer.rb +66 -0
  16. data/pry-0.16.0/lib/pry/command.rb +520 -0
  17. data/pry-0.16.0/lib/pry/command_set.rb +418 -0
  18. data/pry-0.16.0/lib/pry/command_state.rb +36 -0
  19. data/pry-0.16.0/lib/pry/commands/amend_line.rb +103 -0
  20. data/pry-0.16.0/lib/pry/commands/bang.rb +24 -0
  21. data/pry-0.16.0/lib/pry/commands/bang_pry.rb +21 -0
  22. data/pry-0.16.0/lib/pry/commands/cat/abstract_formatter.rb +32 -0
  23. data/pry-0.16.0/lib/pry/commands/cat/exception_formatter.rb +90 -0
  24. data/pry-0.16.0/lib/pry/commands/cat/file_formatter.rb +77 -0
  25. data/pry-0.16.0/lib/pry/commands/cat/input_expression_formatter.rb +48 -0
  26. data/pry-0.16.0/lib/pry/commands/cat.rb +70 -0
  27. data/pry-0.16.0/lib/pry/commands/cd.rb +48 -0
  28. data/pry-0.16.0/lib/pry/commands/change_inspector.rb +34 -0
  29. data/pry-0.16.0/lib/pry/commands/change_prompt.rb +51 -0
  30. data/pry-0.16.0/lib/pry/commands/clear_screen.rb +20 -0
  31. data/pry-0.16.0/lib/pry/commands/code_collector.rb +182 -0
  32. data/pry-0.16.0/lib/pry/commands/disable_pry.rb +31 -0
  33. data/pry-0.16.0/lib/pry/commands/easter_eggs.rb +101 -0
  34. data/pry-0.16.0/lib/pry/commands/edit/exception_patcher.rb +29 -0
  35. data/pry-0.16.0/lib/pry/commands/edit/file_and_line_locator.rb +47 -0
  36. data/pry-0.16.0/lib/pry/commands/edit.rb +225 -0
  37. data/pry-0.16.0/lib/pry/commands/exit.rb +47 -0
  38. data/pry-0.16.0/lib/pry/commands/exit_all.rb +33 -0
  39. data/pry-0.16.0/lib/pry/commands/exit_program.rb +27 -0
  40. data/pry-0.16.0/lib/pry/commands/find_method.rb +199 -0
  41. data/pry-0.16.0/lib/pry/commands/fix_indent.rb +23 -0
  42. data/pry-0.16.0/lib/pry/commands/help.rb +171 -0
  43. data/pry-0.16.0/lib/pry/commands/hist.rb +182 -0
  44. data/pry-0.16.0/lib/pry/commands/import_set.rb +27 -0
  45. data/pry-0.16.0/lib/pry/commands/jump_to.rb +33 -0
  46. data/pry-0.16.0/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/pry-0.16.0/lib/pry/commands/ls/config.rb +54 -0
  48. data/pry-0.16.0/lib/pry/commands/ls/constants.rb +75 -0
  49. data/pry-0.16.0/lib/pry/commands/ls/formatter.rb +55 -0
  50. data/pry-0.16.0/lib/pry/commands/ls/globals.rb +50 -0
  51. data/pry-0.16.0/lib/pry/commands/ls/grep.rb +23 -0
  52. data/pry-0.16.0/lib/pry/commands/ls/instance_vars.rb +40 -0
  53. data/pry-0.16.0/lib/pry/commands/ls/interrogatable.rb +24 -0
  54. data/pry-0.16.0/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  55. data/pry-0.16.0/lib/pry/commands/ls/local_names.rb +37 -0
  56. data/pry-0.16.0/lib/pry/commands/ls/local_vars.rb +47 -0
  57. data/pry-0.16.0/lib/pry/commands/ls/ls_entity.rb +65 -0
  58. data/pry-0.16.0/lib/pry/commands/ls/methods.rb +55 -0
  59. data/pry-0.16.0/lib/pry/commands/ls/methods_helper.rb +50 -0
  60. data/pry-0.16.0/lib/pry/commands/ls/self_methods.rb +34 -0
  61. data/pry-0.16.0/lib/pry/commands/ls.rb +114 -0
  62. data/pry-0.16.0/lib/pry/commands/nesting.rb +29 -0
  63. data/pry-0.16.0/lib/pry/commands/play.rb +113 -0
  64. data/pry-0.16.0/lib/pry/commands/pry_backtrace.rb +30 -0
  65. data/pry-0.16.0/lib/pry/commands/pry_version.rb +21 -0
  66. data/pry-0.16.0/lib/pry/commands/raise_up.rb +38 -0
  67. data/pry-0.16.0/lib/pry/commands/reload_code.rb +74 -0
  68. data/pry-0.16.0/lib/pry/commands/reset.rb +22 -0
  69. data/pry-0.16.0/lib/pry/commands/ri.rb +75 -0
  70. data/pry-0.16.0/lib/pry/commands/save_file.rb +63 -0
  71. data/pry-0.16.0/lib/pry/commands/shell_command.rb +75 -0
  72. data/pry-0.16.0/lib/pry/commands/shell_mode.rb +30 -0
  73. data/pry-0.16.0/lib/pry/commands/show_doc.rb +84 -0
  74. data/pry-0.16.0/lib/pry/commands/show_info.rb +234 -0
  75. data/pry-0.16.0/lib/pry/commands/show_input.rb +22 -0
  76. data/pry-0.16.0/lib/pry/commands/show_source.rb +57 -0
  77. data/pry-0.16.0/lib/pry/commands/stat.rb +44 -0
  78. data/pry-0.16.0/lib/pry/commands/switch_to.rb +29 -0
  79. data/pry-0.16.0/lib/pry/commands/toggle_color.rb +28 -0
  80. data/pry-0.16.0/lib/pry/commands/watch_expression/expression.rb +43 -0
  81. data/pry-0.16.0/lib/pry/commands/watch_expression.rb +108 -0
  82. data/pry-0.16.0/lib/pry/commands/whereami.rb +205 -0
  83. data/pry-0.16.0/lib/pry/commands/wtf.rb +95 -0
  84. data/pry-0.16.0/lib/pry/config/attributable.rb +22 -0
  85. data/pry-0.16.0/lib/pry/config/lazy_value.rb +29 -0
  86. data/pry-0.16.0/lib/pry/config/memoized_value.rb +34 -0
  87. data/pry-0.16.0/lib/pry/config/value.rb +24 -0
  88. data/pry-0.16.0/lib/pry/config.rb +321 -0
  89. data/pry-0.16.0/lib/pry/control_d_handler.rb +28 -0
  90. data/pry-0.16.0/lib/pry/core_extensions.rb +144 -0
  91. data/pry-0.16.0/lib/pry/editor.rb +157 -0
  92. data/pry-0.16.0/lib/pry/env.rb +18 -0
  93. data/pry-0.16.0/lib/pry/exception_handler.rb +48 -0
  94. data/pry-0.16.0/lib/pry/exceptions.rb +73 -0
  95. data/pry-0.16.0/lib/pry/forwardable.rb +27 -0
  96. data/pry-0.16.0/lib/pry/helpers/base_helpers.rb +71 -0
  97. data/pry-0.16.0/lib/pry/helpers/command_helpers.rb +146 -0
  98. data/pry-0.16.0/lib/pry/helpers/documentation_helpers.rb +84 -0
  99. data/pry-0.16.0/lib/pry/helpers/options_helpers.rb +34 -0
  100. data/pry-0.16.0/lib/pry/helpers/platform.rb +55 -0
  101. data/pry-0.16.0/lib/pry/helpers/table.rb +121 -0
  102. data/pry-0.16.0/lib/pry/helpers/text.rb +118 -0
  103. data/pry-0.16.0/lib/pry/helpers.rb +8 -0
  104. data/pry-0.16.0/lib/pry/history.rb +153 -0
  105. data/pry-0.16.0/lib/pry/hooks.rb +180 -0
  106. data/pry-0.16.0/lib/pry/indent.rb +414 -0
  107. data/pry-0.16.0/lib/pry/input/simple_stdio.rb +13 -0
  108. data/pry-0.16.0/lib/pry/input_completer.rb +283 -0
  109. data/pry-0.16.0/lib/pry/input_lock.rb +129 -0
  110. data/pry-0.16.0/lib/pry/inspector.rb +39 -0
  111. data/pry-0.16.0/lib/pry/last_exception.rb +61 -0
  112. data/pry-0.16.0/lib/pry/method/disowned.rb +67 -0
  113. data/pry-0.16.0/lib/pry/method/patcher.rb +131 -0
  114. data/pry-0.16.0/lib/pry/method/weird_method_locator.rb +222 -0
  115. data/pry-0.16.0/lib/pry/method.rb +599 -0
  116. data/pry-0.16.0/lib/pry/object_path.rb +91 -0
  117. data/pry-0.16.0/lib/pry/output.rb +136 -0
  118. data/pry-0.16.0/lib/pry/pager.rb +249 -0
  119. data/pry-0.16.0/lib/pry/prompt.rb +214 -0
  120. data/pry-0.16.0/lib/pry/pry_class.rb +371 -0
  121. data/pry-0.16.0/lib/pry/pry_instance.rb +663 -0
  122. data/pry-0.16.0/lib/pry/repl.rb +326 -0
  123. data/pry-0.16.0/lib/pry/repl_file_loader.rb +79 -0
  124. data/pry-0.16.0/lib/pry/ring.rb +89 -0
  125. data/pry-0.16.0/lib/pry/slop/LICENSE +20 -0
  126. data/pry-0.16.0/lib/pry/slop/commands.rb +190 -0
  127. data/pry-0.16.0/lib/pry/slop/option.rb +210 -0
  128. data/pry-0.16.0/lib/pry/slop.rb +672 -0
  129. data/pry-0.16.0/lib/pry/syntax_highlighter.rb +26 -0
  130. data/pry-0.16.0/lib/pry/system_command_handler.rb +17 -0
  131. data/pry-0.16.0/lib/pry/testable/evalable.rb +24 -0
  132. data/pry-0.16.0/lib/pry/testable/mockable.rb +22 -0
  133. data/pry-0.16.0/lib/pry/testable/pry_tester.rb +88 -0
  134. data/pry-0.16.0/lib/pry/testable/utility.rb +34 -0
  135. data/pry-0.16.0/lib/pry/testable/variables.rb +52 -0
  136. data/pry-0.16.0/lib/pry/testable.rb +68 -0
  137. data/pry-0.16.0/lib/pry/version.rb +5 -0
  138. data/pry-0.16.0/lib/pry/warning.rb +20 -0
  139. data/pry-0.16.0/lib/pry/wrapped_module/candidate.rb +145 -0
  140. data/pry-0.16.0/lib/pry/wrapped_module.rb +382 -0
  141. data/pry-0.16.0/lib/pry.rb +148 -0
  142. data/super-smart-mod.gemspec +12 -0
  143. metadata +182 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Testable
5
+ module Evalable
6
+ def pry_tester(*args, &block)
7
+ args.unshift(Pry.toplevel_binding) if args.empty? || args[0].is_a?(Hash)
8
+ Pry::Testable::PryTester.new(*args).tap do |t|
9
+ t.singleton_class.class_eval(&block) if block
10
+ end
11
+ end
12
+
13
+ def pry_eval(*eval_strs)
14
+ b =
15
+ if eval_strs.first.is_a?(String)
16
+ Pry.toplevel_binding
17
+ else
18
+ Pry.binding_for(eval_strs.shift)
19
+ end
20
+ pry_tester(b).eval(*eval_strs)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ class Pry
6
+ module Testable
7
+ module Mockable
8
+ def mock_command(cmd, args = [], opts = {})
9
+ output = StringIO.new
10
+ pry = Pry.new(output: output)
11
+ ret = cmd.new(opts.merge(pry_instance: pry, output: output)).call_safely(*args)
12
+ Struct.new(:output, :return).new(output.string, ret)
13
+ end
14
+
15
+ def mock_exception(*mock_backtrace)
16
+ StandardError.new.tap do |e|
17
+ e.define_singleton_method(:backtrace) { mock_backtrace }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ class Pry
6
+ module Testable
7
+ class PryTester
8
+ extend Pry::Forwardable
9
+ attr_reader :pry, :out
10
+ def_delegators :@pry, :eval_string, :eval_string=
11
+
12
+ def initialize(target = TOPLEVEL_BINDING, options = {})
13
+ @pry = Pry.new(options.merge(target: target))
14
+ @history = options[:history]
15
+ @pry.inject_sticky_locals!
16
+ reset_output
17
+ end
18
+
19
+ def eval(*strs)
20
+ reset_output
21
+ result = nil
22
+
23
+ strs.flatten.each do |str|
24
+ # Check for space prefix. See #1369.
25
+ str = "#{str.strip}\n" if str !~ /^\s\S/
26
+ @history.push str if @history
27
+
28
+ result =
29
+ if @pry.process_command(str)
30
+ last_command_result_or_output
31
+ else
32
+ # Check if this is a multiline paste.
33
+ begin
34
+ complete_expr = Pry::Code.complete_expression?(str)
35
+ rescue SyntaxError => exception
36
+ @pry.output.puts(
37
+ "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}"
38
+ )
39
+ end
40
+ @pry.evaluate_ruby(str) if complete_expr
41
+ end
42
+ end
43
+
44
+ result
45
+ end
46
+
47
+ def push(*lines)
48
+ Array(lines).flatten.each do |line|
49
+ @pry.eval(line)
50
+ end
51
+ end
52
+
53
+ def push_binding(context)
54
+ @pry.push_binding context
55
+ end
56
+
57
+ def last_output
58
+ @out.string if @out
59
+ end
60
+
61
+ def process_command(command_str)
62
+ @pry.process_command(command_str) || raise("Not a valid command")
63
+ last_command_result_or_output
64
+ end
65
+
66
+ def last_command_result
67
+ result = Pry.current[:pry_cmd_result]
68
+ result.retval if result
69
+ end
70
+
71
+ protected
72
+
73
+ def last_command_result_or_output
74
+ result = last_command_result
75
+ if result != Pry::Command::VOID_VALUE
76
+ result
77
+ else
78
+ last_output
79
+ end
80
+ end
81
+
82
+ def reset_output
83
+ @out = StringIO.new
84
+ @pry.output = @out
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+
5
+ class Pry
6
+ module Testable
7
+ module Utility
8
+ #
9
+ # Creates a Tempfile then unlinks it after the block has yielded.
10
+ #
11
+ # @yieldparam [String] file
12
+ # The path of the temp file
13
+ #
14
+ # @return [void]
15
+ #
16
+ def temp_file(ext = '.rb')
17
+ file = Tempfile.open(['pry', ext])
18
+ yield file
19
+ ensure
20
+ file.close(true) if file
21
+ end
22
+
23
+ def unindent(*args)
24
+ Pry::Helpers::CommandHelpers.unindent(*args)
25
+ end
26
+
27
+ def inner_scope
28
+ catch(:inner_scope) do
29
+ yield -> { throw(:inner_scope, self) }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Testable
5
+ module Variables
6
+ #
7
+ # @example
8
+ # temporary_constants(:Foo, :Bar) do
9
+ # Foo = Class.new(RuntimeError)
10
+ # Bar = Class.new(RuntimeError)
11
+ # end
12
+ # Foo # => NameError
13
+ # Bar # => NameError
14
+ #
15
+ # @param [Array<Symbol>] names
16
+ # An array of constant names that be defined by a block,
17
+ # and removed by this method afterwards.
18
+ #
19
+ # @return [void]
20
+ #
21
+ def temporary_constants(*names)
22
+ names.each do |name|
23
+ Object.remove_const name if Object.const_defined?(name)
24
+ end
25
+ yield
26
+ ensure
27
+ names.each do |name|
28
+ Object.remove_const name if Object.const_defined?(name)
29
+ end
30
+ end
31
+
32
+ #
33
+ # @param [String] name
34
+ # The name of a variable.
35
+ #
36
+ # @param [String] value
37
+ # Its value.
38
+ #
39
+ # @param [Binding] binding
40
+ # The binding object to insert a variable into.
41
+ #
42
+ # @return [void]
43
+ #
44
+ def insert_variable(name, value, binding)
45
+ Pry.current[:pry_local] = value
46
+ binding.eval("#{name} = ::Pry.current[:pry_local]")
47
+ ensure
48
+ Pry.current[:pry_local] = nil
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # good idea ???
4
+ # if you're testing pry plugin you should require pry by yourself, no?
5
+ require 'pry' unless defined?(Pry)
6
+
7
+ class Pry
8
+ module Testable
9
+ require_relative "testable/pry_tester"
10
+ require_relative "testable/evalable"
11
+ require_relative "testable/mockable"
12
+ require_relative "testable/variables"
13
+ require_relative "testable/utility"
14
+
15
+ #
16
+ # When {Pry::Testable} is included into another module or class,
17
+ # the following modules are also included: {Pry::Testable::Mockable},
18
+ # {Pry::Testable::Evalable}, {Pry::Testable::Variables}, and
19
+ # {Pry::Testable::Utility}.
20
+ #
21
+ # @note
22
+ # Each of the included modules mentioned above may also be used
23
+ # standalone or in a pick-and-mix fashion.
24
+ #
25
+ # @param [Module] mod
26
+ # A class or module.
27
+ #
28
+ # @return [void]
29
+ #
30
+ def self.included(mod)
31
+ mod.module_eval do
32
+ include Pry::Testable::Mockable
33
+ include Pry::Testable::Evalable
34
+ include Pry::Testable::Variables
35
+ include Pry::Testable::Utility
36
+ end
37
+ end
38
+
39
+ #
40
+ # Sets various configuration options that make Pry optimal for a test
41
+ # environment, see source code for complete details.
42
+ #
43
+ # @return [void]
44
+ #
45
+ def self.set_testenv_variables
46
+ Pry.config = Pry::Config.new.merge(
47
+ color: false,
48
+ pager: false,
49
+ should_load_rc: false,
50
+ should_load_local_rc: false,
51
+ correct_indent: false,
52
+ collision_warning: false,
53
+ history_save: false,
54
+ history_load: false,
55
+ hooks: Pry::Hooks.new
56
+ )
57
+ end
58
+
59
+ #
60
+ # Reset the Pry configuration to their default values.
61
+ #
62
+ # @return [void]
63
+ #
64
+ def self.unset_testenv_variables
65
+ Pry.config = Pry::Config.new
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ VERSION = '0.16.0'.freeze
5
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # @api private
5
+ # @since v0.13.0
6
+ module Warning
7
+ # Prints a warning message with exact file and line location, similar to how
8
+ # Ruby's -W prints warnings.
9
+ #
10
+ # @param [String] message
11
+ # @return [void]
12
+ def self.warn(message)
13
+ location = caller_locations(2..2).first
14
+ path = location.path
15
+ lineno = location.lineno
16
+
17
+ Kernel.warn("#{path}:#{lineno}: warning: #{message}")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class WrappedModule
5
+ # This class represents a single candidate for a module/class definition.
6
+ # It provides access to the source, documentation, line and file
7
+ # for a monkeypatch (reopening) of a class/module.
8
+ class Candidate
9
+ include Pry::Helpers::DocumentationHelpers
10
+ include Pry::CodeObject::Helpers
11
+ extend Pry::Forwardable
12
+
13
+ # @return [String] The file where the module definition is located.
14
+ attr_reader :file
15
+ alias source_file file
16
+
17
+ # @return [Fixnum] The line where the module definition is located.
18
+ attr_reader :line
19
+ alias source_line line
20
+
21
+ # Methods to delegate to associated `Pry::WrappedModule
22
+ # instance`.
23
+ private_delegates = %i[lines_for_file method_candidates yard_docs? name]
24
+ public_delegates = %i[wrapped module? class? nonblank_name
25
+ number_of_candidates]
26
+
27
+ def_delegators :@wrapper, *public_delegates
28
+ def_private_delegators :@wrapper, *private_delegates
29
+
30
+ # @raise [Pry::CommandError] If `rank` is out of bounds.
31
+ # @param [Pry::WrappedModule] wrapper The associated
32
+ # `Pry::WrappedModule` instance that owns the candidates.
33
+ # @param [Fixnum] rank The rank of the candidate to
34
+ # retrieve. Passing 0 returns 'primary candidate' (the candidate with largest
35
+ # number of methods), passing 1 retrieves candidate with
36
+ # second largest number of methods, and so on, up to
37
+ # `Pry::WrappedModule#number_of_candidates() - 1`
38
+ def initialize(wrapper, rank)
39
+ @wrapper = wrapper
40
+
41
+ if number_of_candidates <= 0
42
+ raise CommandError, "Cannot find a definition for #{name} module!"
43
+ end
44
+
45
+ if rank > (number_of_candidates - 1)
46
+ raise CommandError,
47
+ "No such module candidate. Allowed candidates range is " \
48
+ "from 0 to #{number_of_candidates - 1}"
49
+ end
50
+
51
+ @source = @source_location = nil
52
+ @rank = rank
53
+ @file, @line = source_location
54
+ end
55
+
56
+ # @raise [Pry::CommandError] If source code cannot be found.
57
+ # @return [String] The source for the candidate, i.e the
58
+ # complete module/class definition.
59
+ def source
60
+ return nil if file.nil?
61
+ return @source if @source
62
+
63
+ @source ||= strip_leading_whitespace(
64
+ Pry::Code.from_file(file).expression_at(line, number_of_lines_in_first_chunk)
65
+ )
66
+ end
67
+
68
+ # @raise [Pry::CommandError] If documentation cannot be found.
69
+ # @return [String] The documentation for the candidate.
70
+ def doc
71
+ return nil if file.nil?
72
+
73
+ @doc ||= get_comment_content(Pry::Code.from_file(file).comment_describing(line))
74
+ end
75
+
76
+ # @return [Array, nil] A `[String, Fixnum]` pair representing the
77
+ # source location (file and line) for the candidate or `nil`
78
+ # if no source location found.
79
+ def source_location
80
+ return @source_location if @source_location
81
+
82
+ file, line = first_method_source_location
83
+ return nil unless file.is_a?(String)
84
+
85
+ @source_location = [file, first_line_of_module_definition(file, line)]
86
+ rescue Pry::RescuableException
87
+ nil
88
+ end
89
+
90
+ private
91
+
92
+ # Locate the first line of the module definition.
93
+ # @param [String] file The file that contains the module
94
+ # definition (somewhere).
95
+ # @param [Fixnum] line The module definition should appear
96
+ # before this line (if it exists).
97
+ # @return [Fixnum] The line where the module is defined. This
98
+ # line number is one-indexed.
99
+ def first_line_of_module_definition(file, line)
100
+ searchable_lines = lines_for_file(file)[0..(line - 2)]
101
+ searchable_lines.rindex { |v| module_definition_first_line?(v) } + 1
102
+ end
103
+
104
+ def module_definition_first_line?(line)
105
+ mod_type_string = wrapped.class.to_s.downcase
106
+ wrapped_name_last = wrapped.name.split(/::/).last
107
+ /(^|=)\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped_name_last}/ =~ line ||
108
+ /^\s*(::)?#{wrapped_name_last}\s*?=\s*?#{wrapped.class}/ =~ line ||
109
+ /^\s*(::)?#{wrapped_name_last}\.(class|instance)_eval/ =~ line
110
+ end
111
+
112
+ # This method is used by `Candidate#source_location` as a
113
+ # starting point for the search for the candidate's definition.
114
+ # @return [Array] The source location of the base method used to
115
+ # calculate the source location of the candidate.
116
+ def first_method_source_location
117
+ @first_method_source_location ||= method_candidates[@rank].first.source_location
118
+ end
119
+
120
+ # @return [Array] The source location of the last method in this
121
+ # candidate's module definition.
122
+ def last_method_source_location
123
+ @last_method_source_location ||= method_candidates[@rank].last.source_location
124
+ end
125
+
126
+ # Return the number of lines between the start of the class definition and
127
+ # the start of the last method. We use this value so we can quickly grab
128
+ # these lines from the file (without having to check each intervening line
129
+ # for validity, which is expensive) speeding up source extraction.
130
+ #
131
+ # @return [Integer] number of lines.
132
+ def number_of_lines_in_first_chunk
133
+ # Ruby 4.0+ provides more details, including end of method:
134
+ # https://bugs.ruby-lang.org/issues/6012
135
+ end_method_line = if last_method_source_location.size == 5
136
+ last_method_source_location[-2]
137
+ else
138
+ last_method_source_location.last
139
+ end
140
+
141
+ end_method_line - line
142
+ end
143
+ end
144
+ end
145
+ end