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

Initial implementation of fast show-source command.

This requires an updated method_source gem. This approach works by reading all code between the start of the class definition
and the method with the highest line number in one go. Since we know this chunk of code is valid we can avoid the expensive eval-based validity checks.
Once we have primed the expression buffer with this chunk of code we then start the expensive checks looking for a complete expression, but there shouldn't be
many lines of code left since we've already processed the last method in the class definition. Using this technique i was able to show-source the 2000 line definition of
ActiveRecord::Base in under a second.
This commit is contained in:
John Mair 2012-06-29 05:24:18 +12:00
parent 4714d1835c
commit 2ad9d0befc
3 changed files with 18 additions and 9 deletions

View file

@ -352,8 +352,8 @@ class Pry
#
# @param [Fixnum] line_number (1-based)
# @return [String] the code.
def expression_at(line_number)
self.class.expression_at(raw, line_number)
def expression_at(line_number, consume=0)
self.class.expression_at(raw, line_number, :consume => consume)
end
# Return an unformatted String of the code.

View file

@ -52,8 +52,10 @@ class Pry
return @source if @source
raise CommandError, "Could not locate source for #{wrapped}!" if file.nil?
end_line = end_method_source_location.last
@source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line))
num_lines = end_line - line
@source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line, num_lines))
end
# @raise [Pry::CommandError] If documentation cannot be found.
@ -86,7 +88,7 @@ class Pry
return @source_location if @source_location
mod_type_string = wrapped.class.to_s.downcase
file, line = method_source_location
file, line = start_method_source_location
return nil if !file.is_a?(String)
@ -110,16 +112,22 @@ class Pry
# starting point for the search for the candidate's definition.
# @return [Array] The source location of the base method used to
# calculate the source location of the candidate.
def method_source_location
return @method_source_location if @method_source_location
def start_method_source_location
adjusted_source_location(method_candidates[@rank].first.source_location)
end
file, line = method_candidates[@rank].source_location
def end_method_source_location
adjusted_source_location(method_candidates[@rank].last.source_location)
end
def adjusted_source_location(sl)
file, line = sl
if file && RbxPath.is_core_path?(file)
file = RbxPath.convert_path_to_full(file)
end
@method_source_location = [file, line]
[file, line]
end
# @param [String] doc The raw docstring to process.

View file

@ -213,7 +213,8 @@ class Pry
# the search in uncovering the module definition.
def method_candidates
@method_candidates ||= all_source_locations_by_popularity.map do |group|
group.last.sort_by(&:source_line).first # best candidate for group
methods_sorted_by_source_line = group.last.sort_by(&:source_line)
[methods_sorted_by_source_line.first, methods_sorted_by_source_line.last]
end
end