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)
|
# @param [Fixnum] line_number (1-based)
|
||||||
# @return [String] the code.
|
# @return [String] the code.
|
||||||
def expression_at(line_number)
|
def expression_at(line_number, consume=0)
|
||||||
self.class.expression_at(raw, line_number)
|
self.class.expression_at(raw, line_number, :consume => consume)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return an unformatted String of the code.
|
# Return an unformatted String of the code.
|
||||||
|
|
|
@ -52,8 +52,10 @@ class Pry
|
||||||
return @source if @source
|
return @source if @source
|
||||||
|
|
||||||
raise CommandError, "Could not locate source for #{wrapped}!" if file.nil?
|
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
|
end
|
||||||
|
|
||||||
# @raise [Pry::CommandError] If documentation cannot be found.
|
# @raise [Pry::CommandError] If documentation cannot be found.
|
||||||
|
@ -86,7 +88,7 @@ class Pry
|
||||||
return @source_location if @source_location
|
return @source_location if @source_location
|
||||||
|
|
||||||
mod_type_string = wrapped.class.to_s.downcase
|
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)
|
return nil if !file.is_a?(String)
|
||||||
|
|
||||||
|
@ -110,16 +112,22 @@ class Pry
|
||||||
# starting point for the search for the candidate's definition.
|
# starting point for the search for the candidate's definition.
|
||||||
# @return [Array] The source location of the base method used to
|
# @return [Array] The source location of the base method used to
|
||||||
# calculate the source location of the candidate.
|
# calculate the source location of the candidate.
|
||||||
def method_source_location
|
def start_method_source_location
|
||||||
return @method_source_location if @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)
|
if file && RbxPath.is_core_path?(file)
|
||||||
file = RbxPath.convert_path_to_full(file)
|
file = RbxPath.convert_path_to_full(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
@method_source_location = [file, line]
|
[file, line]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [String] doc The raw docstring to process.
|
# @param [String] doc The raw docstring to process.
|
||||||
|
|
|
@ -213,7 +213,8 @@ class Pry
|
||||||
# the search in uncovering the module definition.
|
# the search in uncovering the module definition.
|
||||||
def method_candidates
|
def method_candidates
|
||||||
@method_candidates ||= all_source_locations_by_popularity.map do |group|
|
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue