pry 0.9.7.4-java → 0.9.8-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +2 -3
  2. data/CHANGELOG +43 -0
  3. data/README.markdown +3 -1
  4. data/Rakefile +51 -32
  5. data/bin/pry +2 -80
  6. data/lib/pry.rb +33 -26
  7. data/lib/pry/cli.rb +152 -0
  8. data/lib/pry/code.rb +351 -0
  9. data/lib/pry/command.rb +422 -0
  10. data/lib/pry/command_set.rb +259 -129
  11. data/lib/pry/commands.rb +0 -1
  12. data/lib/pry/config.rb +43 -9
  13. data/lib/pry/default_commands/context.rb +109 -92
  14. data/lib/pry/default_commands/documentation.rb +174 -63
  15. data/lib/pry/default_commands/easter_eggs.rb +26 -2
  16. data/lib/pry/default_commands/gems.rb +65 -37
  17. data/lib/pry/default_commands/input.rb +175 -243
  18. data/lib/pry/default_commands/introspection.rb +173 -112
  19. data/lib/pry/default_commands/ls.rb +96 -114
  20. data/lib/pry/default_commands/shell.rb +175 -70
  21. data/lib/pry/helpers/base_helpers.rb +7 -2
  22. data/lib/pry/helpers/command_helpers.rb +71 -77
  23. data/lib/pry/helpers/options_helpers.rb +10 -41
  24. data/lib/pry/helpers/text.rb +24 -4
  25. data/lib/pry/history.rb +55 -17
  26. data/lib/pry/history_array.rb +2 -0
  27. data/lib/pry/hooks.rb +252 -0
  28. data/lib/pry/indent.rb +9 -5
  29. data/lib/pry/method.rb +149 -50
  30. data/lib/pry/plugins.rb +12 -4
  31. data/lib/pry/pry_class.rb +69 -26
  32. data/lib/pry/pry_instance.rb +187 -115
  33. data/lib/pry/version.rb +1 -1
  34. data/lib/pry/wrapped_module.rb +73 -0
  35. data/man/pry.1 +195 -0
  36. data/man/pry.1.html +204 -0
  37. data/man/pry.1.ronn +141 -0
  38. data/pry.gemspec +29 -32
  39. data/test/helper.rb +32 -36
  40. data/test/test_cli.rb +78 -0
  41. data/test/test_code.rb +201 -0
  42. data/test/test_command.rb +327 -0
  43. data/test/test_command_integration.rb +512 -0
  44. data/test/test_command_set.rb +338 -12
  45. data/test/test_completion.rb +1 -1
  46. data/test/test_default_commands.rb +1 -2
  47. data/test/test_default_commands/test_context.rb +27 -5
  48. data/test/test_default_commands/test_documentation.rb +20 -8
  49. data/test/test_default_commands/test_input.rb +84 -45
  50. data/test/test_default_commands/test_introspection.rb +74 -17
  51. data/test/test_default_commands/test_ls.rb +9 -36
  52. data/test/test_default_commands/test_shell.rb +240 -13
  53. data/test/test_hooks.rb +490 -0
  54. data/test/test_indent.rb +2 -0
  55. data/test/test_method.rb +60 -0
  56. data/test/test_pry.rb +29 -904
  57. data/test/test_pry_defaults.rb +380 -0
  58. data/test/test_pry_history.rb +24 -24
  59. data/test/test_syntax_checking.rb +63 -0
  60. data/test/test_wrapped_module.rb +71 -0
  61. metadata +50 -39
  62. data/lib/pry/command_context.rb +0 -53
  63. data/lib/pry/command_processor.rb +0 -181
  64. data/lib/pry/extended_commands/user_command_api.rb +0 -65
  65. data/test/test_command_processor.rb +0 -176
@@ -1,4 +1,3 @@
1
- require "pry/command_processor.rb"
2
1
  require "pry/indent"
3
2
 
4
3
  class Pry
@@ -8,7 +7,6 @@ class Pry
8
7
  attr_accessor :commands
9
8
  attr_accessor :print
10
9
  attr_accessor :exception_handler
11
- attr_accessor :hooks
12
10
  attr_accessor :input_stack
13
11
 
14
12
  attr_accessor :custom_completions
@@ -16,13 +14,32 @@ class Pry
16
14
  attr_accessor :binding_stack
17
15
 
18
16
  attr_accessor :last_result
19
- attr_accessor :last_exception
20
17
  attr_accessor :last_file
21
18
  attr_accessor :last_dir
22
19
 
20
+ attr_reader :last_exception
21
+
23
22
  attr_reader :input_array
24
23
  attr_reader :output_array
25
24
 
25
+ attr_accessor :backtrace
26
+
27
+ # Special treatment for hooks as we want to alert people of the
28
+ # changed API
29
+ attr_reader :hooks
30
+
31
+ # FIXME:
32
+ # This is a hack to alert people of the new API.
33
+ # @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
34
+ def hooks=(v)
35
+ if v.is_a?(Hash)
36
+ warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
37
+ @hooks = Pry::Hooks.from_hash(v)
38
+ else
39
+ @hooks = v
40
+ end
41
+ end
42
+
26
43
  # Create a new `Pry` object.
27
44
  # @param [Hash] options The optional configuration parameters.
28
45
  # @option options [#readline] :input The object to use for input.
@@ -35,7 +52,6 @@ class Pry
35
52
  def initialize(options={})
36
53
  refresh(options)
37
54
 
38
- @command_processor = CommandProcessor.new(self)
39
55
  @binding_stack = []
40
56
  @indent = Pry::Indent.new
41
57
  end
@@ -57,7 +73,7 @@ class Pry
57
73
  end
58
74
 
59
75
  defaults.merge!(options).each do |key, value|
60
- send "#{key}=", value
76
+ send("#{key}=", value) if respond_to?("#{key}=")
61
77
  end
62
78
 
63
79
  true
@@ -106,21 +122,14 @@ class Pry
106
122
  @output_array = Pry::HistoryArray.new(size)
107
123
  end
108
124
 
109
- # Execute the hook `hook_name`, if it is defined.
110
- # @param [Symbol] hook_name The hook to execute
111
- # @param [Array] args The arguments to pass to the hook.
112
- def exec_hook(hook_name, *args, &block)
113
- hooks[hook_name].call(*args, &block) if hooks[hook_name]
114
- end
115
-
116
125
  # Make sure special locals exist at start of session
117
126
  def initialize_special_locals(target)
118
127
  inject_local("_in_", @input_array, target)
119
128
  inject_local("_out_", @output_array, target)
120
129
  inject_local("_pry_", self, target)
121
- inject_local("_ex_", nil, target)
122
- inject_local("_file_", nil, target)
123
- inject_local("_dir_", nil, target)
130
+ inject_local("_ex_", last_exception, target)
131
+ inject_local("_file_", last_file, target)
132
+ inject_local("_dir_", last_dir, target)
124
133
 
125
134
  # without this line we get 1 test failure, ask Mon_Ouie
126
135
  set_last_result(nil, target)
@@ -136,13 +145,13 @@ class Pry
136
145
 
137
146
  def special_locals
138
147
  {
139
- :_in_ => @input_array,
140
- :_out_ => @output_array,
141
- :_pry_ => self,
142
- :_ex_ => last_exception,
148
+ :_in_ => @input_array,
149
+ :_out_ => @output_array,
150
+ :_pry_ => self,
151
+ :_ex_ => last_exception,
143
152
  :_file_ => last_file,
144
- :_dir_ => last_dir,
145
- :_ => last_result
153
+ :_dir_ => last_dir,
154
+ :_ => last_result
146
155
  }
147
156
  end
148
157
 
@@ -188,8 +197,9 @@ class Pry
188
197
  end
189
198
  end
190
199
 
200
+ break_data || nil
201
+ ensure
191
202
  repl_epilogue(target)
192
- break_data || target_self
193
203
  end
194
204
 
195
205
  # Perform a read-eval-print.
@@ -232,15 +242,16 @@ class Pry
232
242
 
233
243
  code = r(target)
234
244
 
235
- result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
245
+ result = target.eval(code, Pry.eval_path, Pry.current_line)
246
+ set_last_result(result, target, code)
247
+
236
248
  result
237
- rescue CommandError, Slop::InvalidOptionError => e
238
- output.puts "Error: #{e.message}"
239
- @suppress_output = true
240
249
  rescue RescuableException => e
241
- set_last_exception(e, target)
250
+ self.last_exception = e
251
+ e
242
252
  ensure
243
253
  update_input_history(code)
254
+ exec_hook :after_eval, result, self
244
255
  end
245
256
 
246
257
  # Perform a read.
@@ -259,16 +270,24 @@ class Pry
259
270
 
260
271
  val = ""
261
272
  loop do
262
- val = retrieve_line(eval_string, target)
263
-
264
- # eval_string may be mutated by this method
265
- process_line(val, eval_string, target)
273
+ begin
274
+ # eval_string will probably be mutated by this method
275
+ retrieve_line(eval_string, target)
276
+ rescue CommandError, Slop::InvalidOptionError => e
277
+ output.puts "Error: #{e.message}"
278
+ end
266
279
 
267
- break if valid_expression?(eval_string)
280
+ begin
281
+ break if complete_expression?(eval_string)
282
+ rescue SyntaxError => e
283
+ output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}"
284
+ eval_string = ""
285
+ end
268
286
  end
269
287
 
270
288
  @suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
271
289
 
290
+ exec_hook :after_read, eval_string, self
272
291
  eval_string
273
292
  end
274
293
 
@@ -294,10 +313,15 @@ class Pry
294
313
  end
295
314
  end
296
315
 
297
- # Read a line of input and check for ^d, also determine prompt to use.
298
- # This method should not need to be invoked directly. This method also
299
- # automatically indents the input value using Pry::Indent if auto
300
- # indenting is enabled.
316
+ def should_force_encoding?(eval_string, val)
317
+ eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding
318
+ end
319
+ private :should_force_encoding?
320
+
321
+ # Read and process a line of input -- check for ^D, determine which prompt to
322
+ # use, rewrite the indentation if `Pry.config.auto_indent` is enabled, and,
323
+ # if the line is a command, process it and alter the eval_string accordingly.
324
+ # This method should not need to be invoked directly.
301
325
  #
302
326
  # @param [String] eval_string The cumulative lines of input.
303
327
  # @param [Binding] target The target of the session.
@@ -305,45 +329,60 @@ class Pry
305
329
  def retrieve_line(eval_string, target)
306
330
  @indent.reset if eval_string.empty?
307
331
 
308
- current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
332
+ current_prompt = select_prompt(eval_string, target)
309
333
  indentation = Pry.config.auto_indent ? @indent.indent_level : ''
310
334
 
311
- val = readline(current_prompt + indentation)
335
+ val = readline("#{current_prompt}#{indentation}")
312
336
 
313
337
  # invoke handler if we receive EOF character (^D)
314
338
  if !val
315
339
  output.puts ""
316
340
  Pry.config.control_d_handler.call(eval_string, self)
317
- ""
318
- else
319
- # Change the eval_string into the input encoding (Issue 284)
320
- # TODO: This wouldn't be necessary if the eval_string was constructed from
321
- # input strings only.
322
- if eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding
323
- eval_string.force_encoding(val.encoding)
324
- end
341
+ return
342
+ end
325
343
 
326
- if !@command_processor.valid_command?(val, target) && Pry.config.auto_indent && !input.is_a?(StringIO)
327
- orig_val = "#{indentation}#{val}"
328
- val = @indent.indent(val)
344
+ # Change the eval_string into the input encoding (Issue 284)
345
+ # TODO: This wouldn't be necessary if the eval_string was constructed from
346
+ # input strings only.
347
+ if should_force_encoding?(eval_string, val)
348
+ eval_string.force_encoding(val.encoding)
349
+ end
329
350
 
330
- if orig_val != val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
331
- output.print @indent.correct_indentation(current_prompt + val, orig_val.length - val.length)
332
- end
351
+ if Pry.config.auto_indent && !input.is_a?(StringIO)
352
+ original_val = "#{indentation}#{val}"
353
+ indented_val = @indent.indent(val)
354
+
355
+ if original_val != indented_val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
356
+ output.print @indent.correct_indentation(current_prompt + indented_val, original_val.length - indented_val.length)
357
+ output.flush
333
358
  end
359
+ else
360
+ indented_val = val
361
+ end
334
362
 
335
- Pry.history << val.dup unless input.is_a?(StringIO)
336
- val
363
+ begin
364
+ if !process_command(val, eval_string, target)
365
+ eval_string << "#{indented_val.rstrip}\n" unless val.empty?
366
+ end
367
+ ensure
368
+ Pry.history << indented_val unless input.is_a?(StringIO)
337
369
  end
338
370
  end
339
371
 
340
- # Process the line received.
372
+ # If the given line is a valid command, process it in the context of the
373
+ # current `eval_string` and context.
341
374
  # This method should not need to be invoked directly.
342
375
  # @param [String] val The line to process.
343
376
  # @param [String] eval_string The cumulative lines of input.
344
377
  # @param [Binding] target The target of the Pry session.
345
- def process_line(val, eval_string, target)
346
- result = @command_processor.process_commands(val, eval_string, target)
378
+ # @return [Boolean] `true` if `val` is a command, `false` otherwise
379
+ def process_command(val, eval_string, target)
380
+ result = commands.process_line(val, {
381
+ :target => target,
382
+ :output => output,
383
+ :eval_string => eval_string,
384
+ :pry_instance => self
385
+ })
347
386
 
348
387
  # set a temporary (just so we can inject the value we want into eval_string)
349
388
  Thread.current[:__pry_cmd_result__] = result
@@ -351,16 +390,16 @@ class Pry
351
390
  # note that `result` wraps the result of command processing; if a
352
391
  # command was matched and invoked then `result.command?` returns true,
353
392
  # otherwise it returns false.
354
- if result.command? && !result.void_command?
355
-
356
- # the command that was invoked was non-void (had a return value) and so we make
357
- # the value of the current expression equal to the return value
358
- # of the command.
359
- eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
393
+ if result.command?
394
+ if !result.void_command?
395
+ # the command that was invoked was non-void (had a return value) and so we make
396
+ # the value of the current expression equal to the return value
397
+ # of the command.
398
+ eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
399
+ end
400
+ true
360
401
  else
361
- # only commands should have an empty `val`
362
- # so this ignores their result
363
- eval_string << "#{val.rstrip}\n" if !val.empty?
402
+ false
364
403
  end
365
404
  end
366
405
 
@@ -368,36 +407,63 @@ class Pry
368
407
  # @param [String] val The command (and its params) to execute.
369
408
  # @param [String] eval_string The current input buffer.
370
409
  # @param [Binding] target The binding to use..
371
- # @return [Pry::CommandContext::VOID_VALUE]
410
+ # @return [Pry::Command::VOID_VALUE]
372
411
  # @example
373
412
  # pry_instance.run_command("ls -m")
374
413
  def run_command(val, eval_string = "", target = binding_stack.last)
375
- process_line(val, eval_string, target)
376
- Pry::CommandContext::VOID_VALUE
414
+ commands.process_line(val,
415
+ :eval_string => eval_string,
416
+ :target => target,
417
+ :pry_instance => self,
418
+ :output => output
419
+ )
420
+ Pry::Command::VOID_VALUE
421
+ end
422
+
423
+ # Execute the specified hook.
424
+ # @param [Symbol] name The hook name to execute
425
+ # @param [*Object] args The arguments to pass to the hook
426
+ # @return [Object, Exception] The return value of the hook or the exception raised
427
+ #
428
+ # If executing a hook raises an exception, we log that and then continue sucessfully.
429
+ # To debug such errors, use the global variable $pry_hook_error, which is set as a
430
+ # result.
431
+ def exec_hook(name, *args, &block)
432
+ e_before = hooks.errors.size
433
+ hooks.exec_hook(name, *args, &block).tap do
434
+ hooks.errors[e_before..-1].each do |e|
435
+ output.puts "#{name} hook failed: #{e.class}: #{e.message}"
436
+ output.puts "#{e.backtrace.first}"
437
+ output.puts "(see _pry_.hooks.errors to debug)"
438
+ end
439
+ end
377
440
  end
378
441
 
379
442
  # Set the last result of an eval.
380
443
  # This method should not need to be invoked directly.
381
444
  # @param [Object] result The result.
382
445
  # @param [Binding] target The binding to set `_` on.
383
- def set_last_result(result, target)
446
+ # @param [String] code The code that was run.
447
+ def set_last_result(result, target, code="")
384
448
  @last_result_is_exception = false
385
449
  @output_array << result
386
450
 
387
- self.last_result = result
451
+ self.last_result = result unless code =~ /\A\s*\z/
388
452
  end
389
453
 
390
454
  # Set the last exception for a session.
391
- # This method should not need to be invoked directly.
392
- # @param [Exception] ex The exception.
393
- # @param [Binding] target The binding to set `_ex_` on.
394
- def set_last_exception(ex, target)
455
+ # @param [Exception] ex
456
+ def last_exception=(ex)
395
457
  class << ex
396
458
  attr_accessor :file, :line, :bt_index
397
459
  def bt_source_location_for(index)
398
460
  backtrace[index] =~ /(.*):(\d+)/
399
461
  [$1, $2.to_i]
400
462
  end
463
+
464
+ def inc_bt_index
465
+ @bt_index = (@bt_index + 1) % backtrace.size
466
+ end
401
467
  end
402
468
 
403
469
  ex.bt_index = 0
@@ -405,8 +471,7 @@ class Pry
405
471
 
406
472
  @last_result_is_exception = true
407
473
  @output_array << ex
408
-
409
- self.last_exception = ex
474
+ @last_exception = ex
410
475
  end
411
476
 
412
477
  # Update Pry's internal state after evalling code.
@@ -480,14 +545,17 @@ class Pry
480
545
 
481
546
  # Returns the appropriate prompt to use.
482
547
  # This method should not need to be invoked directly.
483
- # @param [Boolean] first_line Whether this is the first line of input
484
- # (and not multi-line input).
485
- # @param [Object] target_self The receiver of the Pry session.
548
+ # @param [String] eval_string The current input buffer.
549
+ # @param [Binding] target The target Binding of the Pry session.
486
550
  # @return [String] The prompt.
487
- def select_prompt(first_line, target_self)
551
+ def select_prompt(eval_string, target)
552
+ target_self = target.eval('self')
488
553
 
489
- if first_line
554
+ # If input buffer is empty then use normal prompt
555
+ if eval_string.empty?
490
556
  Array(prompt).first.call(target_self, binding_stack.size - 1, self)
557
+
558
+ # Otherwise use the wait prompt (indicating multi-line expression)
491
559
  else
492
560
  Array(prompt).last.call(target_self, binding_stack.size - 1, self)
493
561
  end
@@ -526,45 +594,49 @@ class Pry
526
594
  prompt_stack.size > 1 ? prompt_stack.pop : prompt
527
595
  end
528
596
 
529
- if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == "ruby"
530
- require 'ripper'
531
-
532
- # Determine if a string of code is a valid Ruby expression.
533
- # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
534
- # @param [String] code The code to validate.
535
- # @return [Boolean] Whether or not the code is a valid Ruby expression.
536
- # @example
537
- # valid_expression?("class Hello") #=> false
538
- # valid_expression?("class Hello; end") #=> true
539
- def valid_expression?(code)
540
- !!Ripper::SexpBuilder.new(code).parse
597
+ # Determine if a string of code is a complete Ruby expression.
598
+ # @param [String] code The code to validate.
599
+ # @return [Boolean] Whether or not the code is a complete Ruby expression.
600
+ # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness.
601
+ # @example
602
+ # complete_expression?("class Hello") #=> false
603
+ # complete_expression?("class Hello; end") #=> true
604
+ def complete_expression?(str)
605
+ if defined?(Rubinius::Melbourne19) && RUBY_VERSION =~ /^1\.9/
606
+ Rubinius::Melbourne19.parse_string(str, Pry.eval_path)
607
+ elsif defined?(Rubinius::Melbourne)
608
+ Rubinius::Melbourne.parse_string(str, Pry.eval_path)
609
+ else
610
+ catch(:valid) do
611
+ Helpers::BaseHelpers.silence_warnings do
612
+ eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path)
613
+ end
614
+ end
541
615
  end
542
616
 
543
- elsif RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == 'jruby'
544
-
545
- # JRuby doesn't have Ripper, so use its native parser for 1.9 mode.
546
- def valid_expression?(code)
547
- JRuby.parse(code)
548
- true
549
- rescue SyntaxError
617
+ # Assert that a line which ends with a , is incomplete.
618
+ str !~ /[,]\z/
619
+ rescue SyntaxError => e
620
+ if incomplete_user_input_exception?(e)
550
621
  false
622
+ else
623
+ raise e
551
624
  end
625
+ end
552
626
 
553
- else
554
- require 'ruby_parser'
555
-
556
- # Determine if a string of code is a valid Ruby expression.
557
- # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
558
- # @param [String] code The code to validate.
559
- # @return [Boolean] Whether or not the code is a valid Ruby expression.
560
- # @example
561
- # valid_expression?("class Hello") #=> false
562
- # valid_expression?("class Hello; end") #=> true
563
- def valid_expression?(code)
564
- # NOTE: we're using .dup because RubyParser mutates the input
565
- RubyParser.new.parse(code.dup)
627
+ # Check whether the exception indicates that the user should input more.
628
+ #
629
+ # @param [SyntaxError] the exception object that was raised.
630
+ # @param [Array<String>] The stack frame of the function that executed eval.
631
+ # @return [Boolean]
632
+ #
633
+ def incomplete_user_input_exception?(ex)
634
+ case ex.message
635
+ when /unexpected (\$end|end-of-file|END_OF_FILE)/, # mri, jruby, ironruby
636
+ /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby
637
+ /missing 'end' for/, /: expecting '[})\]]'$/, /can't find string ".*" anywhere before EOF/, /expecting keyword_end/ # rbx
566
638
  true
567
- rescue Racc::ParseError, SyntaxError
639
+ else
568
640
  false
569
641
  end
570
642
  end