pry 0.9.3pre1-i386-mingw32 → 0.9.4-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELOG +53 -0
  2. data/CONTRIBUTORS +13 -0
  3. data/README.markdown +4 -2
  4. data/Rakefile +17 -3
  5. data/TODO +22 -0
  6. data/lib/pry.rb +102 -24
  7. data/lib/pry/command_context.rb +12 -0
  8. data/lib/pry/command_processor.rb +50 -19
  9. data/lib/pry/command_set.rb +17 -7
  10. data/lib/pry/completion.rb +6 -6
  11. data/lib/pry/config.rb +6 -2
  12. data/lib/pry/default_commands/basic.rb +8 -4
  13. data/lib/pry/default_commands/context.rb +84 -36
  14. data/lib/pry/default_commands/documentation.rb +50 -30
  15. data/lib/pry/default_commands/easter_eggs.rb +5 -0
  16. data/lib/pry/default_commands/input.rb +20 -16
  17. data/lib/pry/default_commands/introspection.rb +61 -77
  18. data/lib/pry/default_commands/ls.rb +22 -14
  19. data/lib/pry/default_commands/shell.rb +32 -17
  20. data/lib/pry/extended_commands/user_command_api.rb +32 -1
  21. data/lib/pry/helpers/base_helpers.rb +21 -9
  22. data/lib/pry/helpers/command_helpers.rb +99 -17
  23. data/lib/pry/helpers/text.rb +12 -11
  24. data/lib/pry/history.rb +61 -0
  25. data/lib/pry/plugins.rb +19 -8
  26. data/lib/pry/pry_class.rb +49 -60
  27. data/lib/pry/pry_instance.rb +122 -119
  28. data/lib/pry/version.rb +1 -1
  29. data/pry.gemspec +15 -14
  30. data/test/helper.rb +31 -0
  31. data/test/test_command_processor.rb +8 -87
  32. data/test/test_command_set.rb +40 -2
  33. data/test/test_completion.rb +26 -0
  34. data/test/test_default_commands/test_context.rb +185 -1
  35. data/test/test_default_commands/test_documentation.rb +10 -0
  36. data/test/test_default_commands/test_input.rb +39 -13
  37. data/test/test_default_commands/test_introspection.rb +11 -1
  38. data/test/test_default_commands/test_shell.rb +18 -0
  39. data/test/test_pry.rb +217 -47
  40. data/test/test_pry_history.rb +84 -0
  41. data/test/test_pry_output.rb +44 -0
  42. data/test/test_special_locals.rb +35 -0
  43. metadata +83 -77
@@ -15,9 +15,9 @@ class Pry
15
15
  end
16
16
 
17
17
  # if start_line is not false then add line numbers starting with start_line
18
- def render_output(should_flood, start_line, text)
18
+ def render_output(should_flood, start_line, text, color=:blue)
19
19
  if start_line
20
- text = Pry::Helpers::Text.with_line_numbers text, start_line
20
+ text = Pry::Helpers::Text.with_line_numbers text, start_line, color
21
21
  end
22
22
 
23
23
  if should_flood
@@ -39,12 +39,25 @@ class Pry
39
39
  end
40
40
  end
41
41
 
42
+ # Open a temp file and yield it to the block, closing it after
43
+ # @return [String] The path of the temp file
44
+ def temp_file
45
+ file = Tempfile.new(["tmp", ".rb"])
46
+ yield file
47
+ file.path
48
+ ensure
49
+ file.close
50
+ end
51
+
42
52
  ########### RBX HELPERS #############
53
+ def is_core_rbx_path?(path)
54
+ rbx? &&
55
+ path.start_with?("kernel")
56
+ end
57
+
43
58
  def rbx_core?(meth)
44
- defined?(RUBY_ENGINE) &&
45
- RUBY_ENGINE =~ /rbx/ &&
46
59
  meth.source_location &&
47
- meth.source_location.first.start_with?("kernel")
60
+ is_core_rbx_path?(meth.source_location.first)
48
61
  end
49
62
 
50
63
  def rvm_ruby?(path)
@@ -70,6 +83,28 @@ class Pry
70
83
  end
71
84
  end
72
85
 
86
+ def rbx_convert_path_to_full(path)
87
+ if rvm_ruby?(Rubinius::BIN_PATH)
88
+ rbx_rvm_convert_path_to_full(path)
89
+ else
90
+ rbx_std_convert_path_to_full(path)
91
+ end
92
+ end
93
+
94
+ def rbx_rvm_convert_path_to_full(path)
95
+ ruby_name = File.dirname(Rubinius::BIN_PATH).split("/").last
96
+ source_path = File.join(File.dirname(File.dirname(File.dirname(Rubinius::BIN_PATH))), "src", ruby_name)
97
+ file_name = File.join(source_path, path)
98
+ raise "Cannot find rbx core source" if !File.exists?(file_name)
99
+ file_name
100
+ end
101
+
102
+ def rbx_std_convert_path_to_full(path)
103
+ file_name = File.join(Rubinius::BIN_PATH, "..", path)
104
+ raise "Cannot find rbx core source" if !File.exists?(file_name)
105
+ file_name
106
+ end
107
+
73
108
  def rbx_core_path_line_for(meth)
74
109
  if rvm_ruby?(Rubinius::BIN_PATH)
75
110
  rvm_rbx_core_path_line_for(meth)
@@ -79,21 +114,14 @@ class Pry
79
114
  end
80
115
 
81
116
  def std_rbx_core_path_line_for(meth)
82
- file_name = File.join(Rubinius::BIN_PATH, "..", meth.source_location.first)
83
- raise "Cannot find rbx core source" if !File.exists?(file_name)
84
-
117
+ file_name = rbx_std_convert_path_to_full(meth.source_location.first)
85
118
  start_line = meth.source_location.last
86
119
 
87
120
  [file_name, start_line]
88
121
  end
89
122
 
90
123
  def rvm_rbx_core_path_line_for(meth)
91
- ruby_name = File.dirname(Rubinius::BIN_PATH).split("/").last
92
- source_path = File.join(File.dirname(File.dirname(File.dirname(Rubinius::BIN_PATH))), "src", ruby_name)
93
-
94
- file_name = File.join(source_path, meth.source_location.first)
95
- raise "Cannot find rbx core source" if !File.exists?(file_name)
96
-
124
+ file_name = rbx_rvm_convert_path_to_full(meth.source_location.first)
97
125
  start_line = meth.source_location.last
98
126
 
99
127
  [file_name, start_line]
@@ -111,7 +139,13 @@ class Pry
111
139
  when :ruby
112
140
  if meth.source_location.first == Pry.eval_path
113
141
  start_line = meth.source_location.last
114
- p = Pry.new(:input => StringIO.new(Pry.line_buffer[start_line..-1].join)).r(target)
142
+
143
+ # FIXME this line below needs to be refactored, WAY too
144
+ # much of a hack. We pass nothing to prompt because if
145
+ # prompt uses #inspect (or #pretty_inspect) on the context
146
+ # it can hang the session if the object being inspected on
147
+ # is enormous see: https://github.com/pry/pry/issues/245
148
+ p = Pry.new(:input => StringIO.new(Pry.line_buffer[start_line..-1].join), :prompt => proc {""}, :hooks => {}).r(target)
115
149
  code = strip_leading_whitespace(p)
116
150
  else
117
151
  if rbx_core?(meth)
@@ -255,7 +289,11 @@ class Pry
255
289
  end
256
290
 
257
291
  language_detected = file_type if file_type
258
- CodeRay.scan(contents, language_detected).term
292
+ if Pry.color
293
+ CodeRay.scan(contents, language_detected).term
294
+ else
295
+ contents
296
+ end
259
297
  end
260
298
 
261
299
  # convert negative line numbers to positive by wrapping around
@@ -286,7 +324,7 @@ class Pry
286
324
 
287
325
  def process_yardoc_tag(comment, tag)
288
326
  in_tag_block = nil
289
- output = comment.lines.map do |v|
327
+ comment.lines.map do |v|
290
328
  if in_tag_block && v !~ /^\S/
291
329
  Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
292
330
  elsif in_tag_block
@@ -328,6 +366,50 @@ class Pry
328
366
  code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
329
367
  end
330
368
 
369
+ def invoke_editor(file, line)
370
+ if Pry.config.editor.respond_to?(:call)
371
+ editor_invocation = Pry.config.editor.call(file, line)
372
+ else
373
+ editor_invocation = "#{Pry.config.editor} #{start_line_syntax_for_editor(file, line)}"
374
+ end
375
+
376
+ if jruby?
377
+ begin
378
+ require 'spoon'
379
+ pid = Spoon.spawnp(*editor_invocation.split)
380
+ Process.waitpid(pid)
381
+ rescue FFI::NotFoundError
382
+ run ".#{editor_invocation}"
383
+ end
384
+ else
385
+ run ".#{editor_invocation}"
386
+ end
387
+ end
388
+
389
+ def start_line_syntax_for_editor(file_name, line_number)
390
+ file_name = file_name.gsub(/\//, '\\') if RUBY_PLATFORM =~ /mswin|mingw/
391
+
392
+ # special case 0th line
393
+ return file_name if line_number <= 0
394
+
395
+ case Pry.config.editor
396
+ when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
397
+ "+#{line_number} #{file_name}"
398
+ when /^mate/, /^geany/
399
+ "-l #{line_number} #{file_name}"
400
+ when /^uedit32/
401
+ "#{file_name}/#{line_number}"
402
+ when /^jedit/
403
+ "#{file_name} +line:#{line_number}"
404
+ else
405
+ if RUBY_PLATFORM =~ /mswin|mingw/
406
+ "#{file_name}"
407
+ else
408
+ "+#{line_number} #{file_name}"
409
+ end
410
+ end
411
+ end
412
+
331
413
  def prompt(message, options="Yn")
332
414
  opts = options.scan(/./)
333
415
  optstring = opts.join("/") # case maintained
@@ -1,10 +1,10 @@
1
1
  class Pry
2
2
  module Helpers
3
3
 
4
- # The methods defined on {Text} are available to custom commands via {Pry::CommandContext#text}.
4
+ # The methods defined on {Text} are available to custom commands via {Pry::CommandContext#text}.
5
5
  module Text
6
-
7
- COLORS =
6
+
7
+ COLORS =
8
8
  {
9
9
  "black" => 0,
10
10
  "red" => 1,
@@ -18,7 +18,7 @@ class Pry
18
18
  }
19
19
 
20
20
  class << self
21
-
21
+
22
22
  COLORS.each_pair do |color, value|
23
23
  define_method color do |text|
24
24
  Pry.color ? "\033[0;#{30+value}m#{text}\033[0m" : text.to_s
@@ -31,7 +31,7 @@ class Pry
31
31
 
32
32
  alias_method :grey, :bright_black
33
33
  alias_method :gray, :bright_black
34
-
34
+
35
35
 
36
36
  # Remove any color codes from _text_.
37
37
  #
@@ -41,11 +41,11 @@ class Pry
41
41
  text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
42
42
  end
43
43
 
44
- # Returns _text_ as bold text for use on a terminal.
44
+ # Returns _text_ as bold text for use on a terminal.
45
45
  # _Pry.color_ must be true for this method to perform any transformations.
46
46
  #
47
47
  # @param [String, #to_s] text
48
- # @return [String] _text_
48
+ # @return [String] _text_
49
49
  def bold text
50
50
  Pry.color ? "\e[1m#{text}\e[0m" : text.to_s
51
51
  end
@@ -63,15 +63,16 @@ class Pry
63
63
  end
64
64
 
65
65
  # Returns _text_ in a numbered list, beginning at _offset_.
66
- #
66
+ #
67
67
  # @param [#each_line] text
68
68
  # @param [Fixnum] offset
69
69
  # @return [String]
70
- def with_line_numbers text, offset
70
+ def with_line_numbers(text, offset, color=:blue)
71
71
  lines = text.each_line.to_a
72
+ max_width = (offset + lines.count).to_s.length
72
73
  lines.each_with_index.map do |line, index|
73
- adjusted_index = index + offset
74
- "#{self.blue adjusted_index}: #{line}"
74
+ adjusted_index = (index + offset).to_s.rjust(max_width)
75
+ "#{self.send(color, adjusted_index)}: #{line}"
75
76
  end.join
76
77
  end
77
78
  end
@@ -0,0 +1,61 @@
1
+ class Pry
2
+ # The History class is responsible for maintaining the user's input history, both
3
+ # internally and within Readline::HISTORY.
4
+ class History
5
+ def initialize
6
+ @history = []
7
+ @saved_lines = 0
8
+ end
9
+
10
+ # Loads a file's contents into the input history.
11
+ # @param [String] filename
12
+ # @return [Integer] The number of lines loaded
13
+ def load(filename)
14
+ File.foreach(filename) do |line|
15
+ Readline::HISTORY << line.chomp
16
+ @history << line.chomp
17
+ end
18
+ @saved_lines = @history.length
19
+ end
20
+
21
+ # Appends input history from this session to a file.
22
+ # @param [String] filename
23
+ # @return [Integer] The number of lines saved
24
+ def save(filename)
25
+ history_to_save = @history[@saved_lines..-1]
26
+ File.open(filename, 'a') do |f|
27
+ history_to_save.each { |ln| f.puts ln }
28
+ end
29
+ @saved_lines = @history.length
30
+ history_to_save.length
31
+ end
32
+
33
+ # Adds a line to the input history, ignoring blank and duplicate lines.
34
+ # @param [String] line
35
+ # @return [String] The same line that was passed in
36
+ def push(line)
37
+ unless line.empty? || (@history.last && line.strip == @history.last.strip)
38
+ Readline::HISTORY << line
39
+ @history << line
40
+ end
41
+ line
42
+ end
43
+ alias << push
44
+
45
+ # Clears all history. Anything the user entered before this point won't be
46
+ # saved, but anything they put in afterwards will still be appended to the
47
+ # history file on exit.
48
+ def clear
49
+ Readline::HISTORY.shift until Readline::HISTORY.empty?
50
+ @history = []
51
+ @saved_lines = 0
52
+ end
53
+
54
+ # Returns an Array containing all stored history.
55
+ # @return [Array<String>] An Array containing all lines of history loaded
56
+ # or entered by the user in the current session.
57
+ def to_a
58
+ @history.dup
59
+ end
60
+ end
61
+ end
data/lib/pry/plugins.rb CHANGED
@@ -1,9 +1,17 @@
1
1
  class Pry
2
2
  class PluginManager
3
3
  PRY_PLUGIN_PREFIX = /^pry-/
4
- PluginNotFound = Class.new(LoadError)
5
4
 
6
- MessageSink = Object.new.tap { |o| def o.method_missing(*args) end }
5
+ # Placeholder when no associated gem found, displays warning
6
+ class NoPlugin
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def method_missing(*args)
12
+ $stderr.puts "Warning: The plugin '#{@name}' was not found! (no gem found)"
13
+ end
14
+ end
7
15
 
8
16
  class Plugin
9
17
  attr_accessor :name, :gem_name, :enabled, :spec, :active
@@ -12,22 +20,25 @@ class Pry
12
20
  @name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec
13
21
  end
14
22
 
15
- # Disable a plugin.
23
+ # Disable a plugin. (prevents plugin from being loaded, cannot
24
+ # disable an already activated plugin)
16
25
  def disable!
17
26
  self.enabled = false
18
27
  end
19
28
 
20
- # Enable a plugin.
29
+ # Enable a plugin. (does not load it immediately but puts on
30
+ # 'white list' to be loaded)
21
31
  def enable!
22
32
  self.enabled = true
23
33
  end
24
34
 
25
- # Activate the plugin (require the gem).
35
+ # Activate the plugin (require the gem - enables/loads the
36
+ # plugin immediately at point of call, even if plugin is disabled)
26
37
  def activate!
27
38
  begin
28
- require gem_name
39
+ require gem_name if !active?
29
40
  rescue LoadError
30
- $stderr.puts "Warning: The plugin '#{gem_name}' was not found!"
41
+ $stderr.puts "Warning: The plugin '#{gem_name}' was not found! (gem found but could not be loaded)"
31
42
  end
32
43
  self.active = true
33
44
  self.enabled = true
@@ -55,7 +66,7 @@ class Pry
55
66
  # @return [Hash] A hash with all plugin names (minus the 'pry-') as
56
67
  # keys and Plugin objects as values.
57
68
  def plugins
58
- h = Pry.config.plugins.strict_loading ? {} : Hash.new { MessageSink }
69
+ h = Hash.new { |_, key| NoPlugin.new(key) }
59
70
  @plugins.each do |plugin|
60
71
  h[plugin.name] = plugin
61
72
  end
data/lib/pry/pry_class.rb CHANGED
@@ -18,26 +18,6 @@ class Pry
18
18
  def_delegators delagatee, *names.map { |v| "#{v}=" }
19
19
  end
20
20
 
21
- # Get nesting data.
22
- # This method should not need to be accessed directly.
23
- # @return [Array] The unparsed nesting information.
24
- attr_reader :nesting
25
-
26
- # Get last value evaluated by Pry.
27
- # This method should not need to be accessed directly.
28
- # @return [Object] The last result.
29
- attr_accessor :last_result
30
-
31
- # Get last exception raised.
32
- # This method should not need to be accessed directly.
33
- # @return [Exception] The last exception.
34
- attr_accessor :last_exception
35
-
36
- # Get the active Pry instance that manages the active Pry session.
37
- # This method should not need to be accessed directly.
38
- # @return [Pry] The active Pry instance.
39
- attr_accessor :active_instance
40
-
41
21
  # Get/Set the Proc that defines extra Readline completions (on top
42
22
  # of the ones defined for IRB).
43
23
  # @return [Proc] The Proc that defines extra Readline completions (on top
@@ -45,10 +25,6 @@ class Pry
45
25
  # Pry.custom_completions = proc { Dir.entries('.') }
46
26
  attr_accessor :custom_completions
47
27
 
48
- # Value returned by last executed Pry command.
49
- # @return [Object] The command value
50
- attr_accessor :cmd_ret_value
51
-
52
28
  # @return [Fixnum] The current input line.
53
29
  attr_accessor :current_line
54
30
 
@@ -62,9 +38,15 @@ class Pry
62
38
  # @return [OpenStruct] Return Pry's config object.
63
39
  attr_accessor :config
64
40
 
41
+ # @return [History] Return Pry's line history object.
42
+ attr_accessor :history
43
+
65
44
  # @return [Boolean] Whether Pry was activated from the command line.
66
45
  attr_accessor :cli
67
46
 
47
+ # @return [Fixnum] The number of active Pry sessions.
48
+ attr_accessor :active_sessions
49
+
68
50
  # plugin forwardables
69
51
  def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
70
52
 
@@ -113,34 +95,40 @@ class Pry
113
95
  new(options).repl(target)
114
96
  end
115
97
 
116
- # A custom version of `Kernel#pretty_inspect`.
117
- # This method should not need to be accessed directly.
118
- # @param obj The object to view.
119
- # @return [String] The string representation of `obj`.
120
- def self.view(obj)
121
- obj.pretty_inspect
122
-
123
- rescue NoMethodError
124
- "unknown"
125
- end
126
-
127
98
  # A version of `Pry.view` that clips the output to `max_size` chars.
128
99
  # In case of > `max_size` chars the `#<Object...> notation is used.
129
100
  # @param obj The object to view.
130
101
  # @param max_size The maximum number of chars before clipping occurs.
131
102
  # @return [String] The string representation of `obj`.
132
- def self.view_clip(obj, max_size=60)
133
- if obj.inspect.size < max_size
103
+ def self.view_clip(obj, max_length = 60)
104
+ if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max_length
105
+ obj.name.to_s
106
+ elsif TOPLEVEL_BINDING.eval('self') == obj
107
+ # special case for 'main' object :)
108
+ obj.inspect
109
+ elsif [String, Numeric, Symbol, nil, true, false].any? { |v| v === obj } && obj.inspect.length <= max_length
134
110
  obj.inspect
135
111
  else
136
- "#<#{obj.class}:%#x>" % (obj.object_id << 1)
112
+ "#<#{obj.class}>"#:%x>"# % (obj.object_id << 1)
137
113
  end
114
+
115
+ rescue RescuableException
116
+ "unknown"
138
117
  end
139
118
 
140
119
  # Load Readline history if required.
141
120
  def self.load_history
142
- history_file = File.expand_path(Pry.config.history.file)
143
- Readline::HISTORY.push(*File.readlines(history_file).map(&:chomp)) if File.exists?(history_file)
121
+ Pry.history.load(history_file) if File.exists?(history_file)
122
+ end
123
+
124
+ # Save new lines of Readline history if required.
125
+ def self.save_history
126
+ Pry.history.save(history_file)
127
+ end
128
+
129
+ # Get the full path of the history_path for pry.
130
+ def self.history_file
131
+ File.expand_path(Pry.config.history.file)
144
132
  end
145
133
 
146
134
  # @return [Boolean] Whether this is the first time a Pry session has
@@ -175,14 +163,14 @@ class Pry
175
163
 
176
164
  output = options[:show_output] ? options[:output] : StringIO.new
177
165
 
178
- Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands]).rep(options[:context])
166
+ Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands], :prompt => proc {""}, :hooks => {}).rep(options[:context])
179
167
  end
180
168
 
181
169
  def self.default_editor_for_platform
182
170
  if RUBY_PLATFORM =~ /mswin|mingw/
183
- ENV['EDITOR'] ? ENV['EDITOR'] : "notepad"
171
+ ENV['VISUAL'] || ENV['EDITOR'] || "notepad"
184
172
  else
185
- ENV['EDITOR'] ? ENV['EDITOR'] : "nano"
173
+ ENV['VISUAL'] || ENV['EDITOR'] || "nano"
186
174
  end
187
175
  end
188
176
 
@@ -203,7 +191,6 @@ class Pry
203
191
 
204
192
  config.plugins ||= OpenStruct.new
205
193
  config.plugins.enabled = true
206
- config.plugins.strict_loading = true
207
194
 
208
195
  config.requires ||= []
209
196
  config.should_load_requires = true
@@ -213,8 +200,20 @@ class Pry
213
200
  config.history.should_load = true
214
201
  config.history.file = File.expand_path("~/.pry_history")
215
202
 
203
+ config.control_d_handler = DEFAULT_CONTROL_D_HANDLER
204
+
216
205
  config.memory_size = 100
217
- config.results_pager = true
206
+
207
+ Pry.config.ls ||= OpenStruct.new
208
+ Pry.config.ls.local_var_color = :bright_red
209
+ Pry.config.ls.instance_var_color = :bright_blue
210
+ Pry.config.ls.class_var_color = :blue
211
+ Pry.config.ls.global_var_color = :bright_magenta
212
+ Pry.config.ls.method_color = :green
213
+ Pry.config.ls.instance_method_color = :bright_green
214
+ Pry.config.ls.constant_color = :yellow
215
+
216
+ Pry.config.ls.separator = " "
218
217
  end
219
218
 
220
219
  # Set all the configurable options back to their default values
@@ -225,32 +224,22 @@ class Pry
225
224
 
226
225
  self.custom_completions = DEFAULT_CUSTOM_COMPLETIONS
227
226
  self.cli = false
228
- self.current_line = 0
229
- self.line_buffer = []
227
+ self.current_line = 1
228
+ self.line_buffer = [""]
230
229
  self.eval_path = "(pry)"
230
+ self.active_sessions = 0
231
231
  end
232
232
 
233
233
  # Basic initialization.
234
234
  def self.init
235
235
  @plugin_manager ||= PluginManager.new
236
-
237
236
  self.config ||= Config.new
237
+ self.history ||= History.new
238
+
238
239
  reset_defaults
239
240
  locate_plugins
240
241
  end
241
242
 
242
- @nesting = []
243
- def @nesting.level
244
- last.is_a?(Array) ? last.first : nil
245
- end
246
-
247
- # Return all active Pry sessions.
248
- # @return [Array<Pry>] Active Pry sessions.
249
- def self.sessions
250
- # last element in nesting array is the pry instance
251
- nesting.map(&:last)
252
- end
253
-
254
243
  # Return a `Binding` object for `target` or return `target` if it is
255
244
  # already a `Binding`.
256
245
  # In the case where `target` is top-level then return `TOPLEVEL_BINDING`