1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

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.
This commit is contained in:
John Mair 2012-04-11 01:39:29 +12:00
parent ff8efd035b
commit 8d0fa78ce5
6 changed files with 71 additions and 53 deletions

View file

@ -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<String>] 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<String>] 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.
#

View file

@ -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

View file

@ -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

View file

@ -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<String>] 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.

View file

@ -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

View file

@ -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