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

Rely on the next version of method_source's CodeHelpers

Cleans up a lot of duplication of hairy code.
This commit is contained in:
Conrad Irwin 2012-06-03 01:55:07 -07:00
parent b313a03c8f
commit 6733439b29
4 changed files with 31 additions and 88 deletions

View file

@ -27,71 +27,7 @@ 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 , or \ is incomplete.
str !~ /[,\\]\s*\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/, /expecting kWHEN/ # rbx
true
else
false
end
end
private :incomplete_user_input_exception?
# 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_or_lines.each_line.to_a
code = ""
lines.each do |v|
code << v
return code if complete_expression?(code)
end
nil
end
include MethodSource::CodeHelpers
# Instantiate a `Code` object containing code loaded from a file or
# Pry's line buffer.
@ -398,6 +334,22 @@ class Pry
lines.map { |l| "#{l.first}\n" }.join
end
# Get the comment that describes the expression on the given line number.
#
# @param [Fixnum] line_number (1-based)
# @return [String] the code.
def comment_describing(line_number)
self.class.comment_describing(raw, line_number)
end
# Get the multiline expression that starts on the given line number.
#
# @param [Fixnum] line_number (1-based)
# @return [String] the code.
def expression_at(line_number)
self.class.expression_at(raw, line_number)
end
# Return an unformatted String of the code.
#
# @return [String]

View file

@ -253,12 +253,16 @@ class Pry
code = strip_comments_from_c_code(info.source)
end
when :ruby
if Helpers::BaseHelpers.rbx? && !pry_method?
code = core_code
elsif pry_method?
code = Pry::Code.retrieve_complete_expression_from(Pry.line_buffer[source_line..-1])
else
code = @method.source
# clone of MethodSource.source_helper that knows to use our
# hacked version of source_location for rbx core methods, and
# our input buffer for methods defined in (pry)
file, line = *source_location
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file
begin
code = Pry::Code.from_file(file).expression_at(line)
rescue SyntaxError => e
raise MethodSource::SourceNotFoundError.new(e.message)
end
strip_leading_whitespace(code)
end

View file

@ -273,7 +273,7 @@ class Pry
begin
# eval_string will probably be mutated by this method
retrieve_line(eval_string, target)
rescue CommandError, Slop::InvalidOptionError => e
rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
output.puts "Error: #{e.message}"
end

View file

@ -152,7 +152,7 @@ class Pry
file, line = module_source_location_for_candidate(idx)
raise CommandError, "Could not locate source for #{wrapped}!" if file.nil?
strip_leading_whitespace(Pry::Code.retrieve_complete_expression_from(lines_for_file(file)[(line - 1)..-1]))
strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line))
end
def source_file
@ -216,8 +216,6 @@ class Pry
idx = search_lines.rindex { |v| class_regexes.any? { |r| r =~ v } }
[file, idx + 1]
rescue Pry::RescuableException
nil
end
def extract_doc
@ -225,20 +223,9 @@ class Pry
end
def extract_doc_for_candidate(idx)
_, line_num = module_source_location_for_candidate(idx)
file, line_num = module_source_location_for_candidate(idx)
buffer = ""
lines_for_file(source_file_for_candidate(idx))[0..(line_num - 2)].each do |line|
# Add any line that is a valid ruby comment,
# but clear as soon as we hit a non comment line.
if (line =~ /^\s*#/) || (line =~ /^\s*$/)
buffer << line.lstrip
else
buffer.replace("")
end
end
buffer
Pry::Code.from_file(file).comment_describing(line_num)
end
# FIXME: this method is also found in Pry::Method