From 8d0fa78ce56558bcfdf8b5e71c6f042548199716 Mon Sep 17 00:00:00 2001 From: John Mair Date: Wed, 11 Apr 2012 01:39:29 +1200 Subject: [PATCH] moved Pry#complete_expression? et al to Pry::Code * This is so we can use it without needing a Pry instance present, it also feels like a more natural home for it. --- lib/pry/code.rb | 65 +++++++++++++++++++++++++++++ lib/pry/command.rb | 2 +- lib/pry/default_commands/editing.rb | 2 +- lib/pry/pry_instance.rb | 49 +--------------------- test/test_pry.rb | 2 +- test/test_syntax_checking.rb | 4 +- 6 files changed, 71 insertions(+), 53 deletions(-) diff --git a/lib/pry/code.rb b/lib/pry/code.rb index d73967ef..4af95397 100644 --- a/lib/pry/code.rb +++ b/lib/pry/code.rb @@ -27,6 +27,71 @@ class Pry # object. class Code class << self + + # Determine if a string of code is a complete Ruby expression. + # @param [String] code The code to validate. + # @return [Boolean] Whether or not the code is a complete Ruby expression. + # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness. + # @example + # complete_expression?("class Hello") #=> false + # complete_expression?("class Hello; end") #=> true + def complete_expression?(str) + if defined?(Rubinius::Melbourne19) && RUBY_VERSION =~ /^1\.9/ + Rubinius::Melbourne19.parse_string(str, Pry.eval_path) + elsif defined?(Rubinius::Melbourne) + Rubinius::Melbourne.parse_string(str, Pry.eval_path) + else + catch(:valid) do + Helpers::BaseHelpers.silence_warnings do + eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path) + end + end + end + + # Assert that a line which ends with a , is incomplete. + str !~ /[,]\z/ + rescue SyntaxError => e + if incomplete_user_input_exception?(e) + false + else + raise e + end + end + + # Check whether the exception indicates that the user should input more. + # + # @param [SyntaxError] the exception object that was raised. + # @param [Array] The stack frame of the function that executed eval. + # @return [Boolean] + # + def incomplete_user_input_exception?(ex) + case ex.message + when /unexpected (\$end|end-of-file|END_OF_FILE)/, # mri, jruby, ironruby + /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby + /missing 'end' for/, /: expecting '[})\]]'$/, /can't find string ".*" anywhere before EOF/, /: expecting keyword_end/ # rbx + true + else + false + end + end + + # Retrieve the first complete expression from the passed string. + # + # @param [String, Array] str The string (or array of lines) to extract the complete + # expression from. + # @return [String, nil] The first complete expression, or `nil` if + # none found. + def retrieve_complete_expression_from(str_or_lines) + lines = str_or_lines.is_a?(Array) ? str_or_lines : str.each_line.to_a + + code = "" + lines.each do |v| + code << v + return code if complete_expression?(code) + end + nil + end + # Instantiate a `Code` object containing code loaded from a file or # Pry's line buffer. # diff --git a/lib/pry/command.rb b/lib/pry/command.rb index 9e54eb49..669880fb 100644 --- a/lib/pry/command.rb +++ b/lib/pry/command.rb @@ -322,7 +322,7 @@ class Pry block_init_string = arg_string.slice!(block_index..-1)[1..-1] prime_string = "proc #{block_init_string}\n" - if !_pry_.complete_expression?(prime_string) + if !Pry::Code.complete_expression?(prime_string) block_string = _pry_.r(target, prime_string) else block_string = prime_string diff --git a/lib/pry/default_commands/editing.rb b/lib/pry/default_commands/editing.rb index 14496341..0cbbd104 100644 --- a/lib/pry/default_commands/editing.rb +++ b/lib/pry/default_commands/editing.rb @@ -379,7 +379,7 @@ class Pry def process perform_play - run "show-input" unless _pry_.complete_expression?(eval_string) + run "show-input" unless Pry::Code.complete_expression?(eval_string) end def process_non_opt diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 192f7aa6..f556cccb 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -293,7 +293,7 @@ class Pry end begin - break if complete_expression?(eval_string) + break if Pry::Code.complete_expression?(eval_string) rescue SyntaxError => e output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}" eval_string = "" @@ -635,53 +635,6 @@ class Pry prompt_stack.size > 1 ? prompt_stack.pop : prompt end - # Determine if a string of code is a complete Ruby expression. - # @param [String] code The code to validate. - # @return [Boolean] Whether or not the code is a complete Ruby expression. - # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness. - # @example - # complete_expression?("class Hello") #=> false - # complete_expression?("class Hello; end") #=> true - def complete_expression?(str) - if defined?(Rubinius::Melbourne19) && RUBY_VERSION =~ /^1\.9/ - Rubinius::Melbourne19.parse_string(str, Pry.eval_path) - elsif defined?(Rubinius::Melbourne) - Rubinius::Melbourne.parse_string(str, Pry.eval_path) - else - catch(:valid) do - Helpers::BaseHelpers.silence_warnings do - eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path) - end - end - end - - # Assert that a line which ends with a , is incomplete. - str !~ /[,]\z/ - rescue SyntaxError => e - if incomplete_user_input_exception?(e) - false - else - raise e - end - end - - # Check whether the exception indicates that the user should input more. - # - # @param [SyntaxError] the exception object that was raised. - # @param [Array] The stack frame of the function that executed eval. - # @return [Boolean] - # - def incomplete_user_input_exception?(ex) - case ex.message - when /unexpected (\$end|end-of-file|END_OF_FILE)/, # mri, jruby, ironruby - /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby - /missing 'end' for/, /: expecting '[})\]]'$/, /can't find string ".*" anywhere before EOF/, /: expecting keyword_end/ # rbx - true - else - false - end - end - # Raise an exception out of Pry. # # See Kernel#raise for documentation of parameters. diff --git a/test/test_pry.rb b/test/test_pry.rb index ca9a837b..d7b68de9 100644 --- a/test/test_pry.rb +++ b/test/test_pry.rb @@ -188,7 +188,7 @@ describe Pry do it "should not mutate the input!" do clean = "puts <<-FOO\nhi\nFOO\n" a = clean.dup - Pry.new.complete_expression?(a) + Pry::Code.complete_expression?(a) a.should == clean end end diff --git a/test/test_syntax_checking.rb b/test/test_syntax_checking.rb index 8ae27b96..5527e048 100644 --- a/test/test_syntax_checking.rb +++ b/test/test_syntax_checking.rb @@ -49,12 +49,12 @@ describe Pry do it "should allow trailing , to continue the line" do pry = Pry.new - pry.complete_expression?("puts 1, 2,").should == false + Pry::Code.complete_expression?("puts 1, 2,").should == false end it "should complete an expression that contains a line ending with a ," do pry = Pry.new - pry.complete_expression?("puts 1, 2,\n3").should == true + Pry::Code.complete_expression?("puts 1, 2,\n3").should == true end it "should not clobber _ex_ on a SyntaxError in the repl" do