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:
parent
4714d1835c
commit
2ad9d0befc
3 changed files with 18 additions and 9 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue