module MethodSource::CodeHelpers
Public Instance Methods
Source
# File lib/method_source/code_helpers.rb, line 52 def comment_describing(file, line_number) lines = file.is_a?(Array) ? file : file.each_line.to_a extract_last_comment(lines[0..(line_number - 2)]) end
Retrieve the comment describing the expression on the given line of the given file.
This is useful to get module or method documentation.
@param [Array<String>, File, String] file The file to parse, either as a File or as
a String or an Array of lines.
@param [Integer] line_number The line number at which to look.
NOTE: The first line in a file is line 1!
@return [String] The comment
Source
# File lib/method_source/code_helpers.rb, line 66 def complete_expression?(str) old_verbose = $VERBOSE $VERBOSE = nil catch(:valid) do eval("BEGIN{throw :valid}\n#{str}") end # Assert that a line which ends with a , or \ is incomplete. str !~ /[,\\]\s*\z/ rescue IncompleteExpression false ensure $VERBOSE = old_verbose end
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 complete_expression?("class 123") #=> SyntaxError: unexpected tINTEGER
Source
# File lib/method_source/code_helpers.rb, line 20 def expression_at(file, line_number, options={}) options = { :strict => false, :consume => 0 }.merge!(options) lines = file.is_a?(Array) ? file : file.each_line.to_a relevant_lines = lines[(line_number - 1)..-1] || [] extract_first_expression(relevant_lines, options[:consume]) rescue SyntaxError => e raise if options[:strict] begin extract_first_expression(relevant_lines) do |code| code.gsub(/\#\{.*?\}/, "temp") end rescue SyntaxError raise e end end
Retrieve the first expression starting on the given line of the given file.
This is useful to get module or method source code.
@param [Array<String>, File, String] file The file to parse, either as a File or as @param [Integer] line_number The line number at which to look.
NOTE: The first line in a file is line 1!
@param [Hash] options The optional configuration parameters. @option options [Boolean] :strict If set to true, then only completely
valid expressions are returned. Otherwise heuristics are used to extract expressions that may have been valid inside an eval.
@option options [Integer] :consume A number of lines to automatically
consume (add to the expression buffer) without checking for validity.
@return [String] The first complete expression @raise [SyntaxError] If the first complete expression can’t be identified
Private Instance Methods
Source
# File lib/method_source/code_helpers.rb, line 92 def extract_first_expression(lines, consume=0, &block) code = consume.zero? ? +"" : lines.slice!(0..(consume - 1)).join lines.each do |v| code << v return code if complete_expression?(block ? block.call(code) : code) end raise SyntaxError, "unexpected $end" end
Get the first expression from the input.
@param [Array<String>] lines @param [Integer] consume A number of lines to automatically
consume (add to the expression buffer) without checking for validity.
@yield a clean-up function to run before checking for complete_expression @return [String] a valid ruby expression @raise [SyntaxError]
Source
# File lib/method_source/code_helpers.rb, line 106 def extract_last_comment(lines) buffer = +"" lines.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.clear end end buffer end
Get the last comment from the input.
@param [Array<String>] lines @return [String]