From 6733439b29dd770a2dcfbcaa1128b3ec64e83f19 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sun, 3 Jun 2012 01:55:07 -0700 Subject: [PATCH] Rely on the next version of method_source's CodeHelpers Cleans up a lot of duplication of hairy code. --- lib/pry/code.rb | 82 ++++++++------------------------------- lib/pry/method.rb | 16 +++++--- lib/pry/pry_instance.rb | 2 +- lib/pry/wrapped_module.rb | 19 ++------- 4 files changed, 31 insertions(+), 88 deletions(-) diff --git a/lib/pry/code.rb b/lib/pry/code.rb index 9ef984fe..16a96ddb 100644 --- a/lib/pry/code.rb +++ b/lib/pry/code.rb @@ -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] 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] 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] diff --git a/lib/pry/method.rb b/lib/pry/method.rb index 8ddb573a..265ce348 100644 --- a/lib/pry/method.rb +++ b/lib/pry/method.rb @@ -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 diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 49b29531..d9f930b2 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -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 diff --git a/lib/pry/wrapped_module.rb b/lib/pry/wrapped_module.rb index 35c5931d..8ab50392 100644 --- a/lib/pry/wrapped_module.rb +++ b/lib/pry/wrapped_module.rb @@ -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