class MetricFu::LineNumbers
Attributes
file_path[R]
Public Class Methods
new(contents, file_path = "")
click to toggle source
Parses ruby code to collect line numbers for class, module, and method definitions. Used by metrics that don't provide line numbers for class, module, or methods problems @param contents [String] a string of ruby code @param file_path
[String] the file path for the contents, defaults to empty string
# File lib/metric_fu/data_structures/line_numbers.rb, line 10 def initialize(contents, file_path = "") @file_path = file_path @locations = {} if contents.to_s.size.zero? mf_log "NON PARSEABLE INPUT: File is empty at path #{file_path.inspect}\n\t#{caller.join("\n\t")}" else parse_code(contents) end end
Public Instance Methods
in_method?(line_number)
click to toggle source
@param line_number [Integer] @return [Boolean] if the given line number is in a method
# File lib/metric_fu/data_structures/line_numbers.rb, line 22 def in_method?(line_number) not method_at_line(line_number) == :no_method_at_line end
method_at_line(line_number)
click to toggle source
@param line_number [Integer] @return [String, nil] the method which includes that line number, if any For all collected locations, find the first location
where the line_number_range includes the line_number. If a location is found, return the method name (first element) Else return :no_method_at_line
# File lib/metric_fu/data_structures/line_numbers.rb, line 32 def method_at_line(line_number) default_proc = -> { [:no_method_at_line] } @locations.detect(default_proc) do |_method_name, line_number_range| line_number_range.include?(line_number) end.first end
start_line_for_method(method)
click to toggle source
@param method [String] the method name being queried @return [Integer, nil] the line number at which the given method is defined
# File lib/metric_fu/data_structures/line_numbers.rb, line 41 def start_line_for_method(method) return nil unless @locations.has_key?(method) @locations[method].first end
Private Instance Methods
parse_code(contents)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 48 def parse_code(contents) file_sexp = MetricFu::SexpNode.parse(contents) file_sexp && process_ast(file_sexp) rescue => e # catch errors for files ruby_parser fails on mf_log "RUBY PARSE FAILURE: #{e.class}\t#{e.message}\tFILE:#{file_path}\tSEXP:#{file_sexp.inspect}\n\tCONTENT:#{contents.inspect}\n\t#{e.backtrace}" end
process_ast(file_sexp)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 56 def process_ast(file_sexp) node = MetricFu::SexpNode.new(file_sexp) case node.node_type when nil mf_log "No ruby code found in #{file_path}" when :class process_class(node) when :module process_module(node) else mf_debug "SEXP: Parsing line numbers for classes in sexp type #{node.node_type.inspect}" mf_debug " in #{file_path}" node.each_module { |child_node| process_class(child_node) } node.each_class { |child_node| process_class(child_node) } end end
process_class(class_node, module_name = nil)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 82 def process_class(class_node, module_name = nil) class_name = class_node.name process_singleton_methods(class_node, class_name) process_instance_methods(class_node, class_name, module_name) process_class_methods(class_node, class_name, module_name) end
process_class_methods(class_node, class_name, module_name)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 105 def process_class_methods(class_node, class_name, module_name) class_node.each_class_method do |class_method_node| class_method_name = class_method_node.full_name(module_name, class_name) @locations[class_method_name] = class_method_node.line_range end end
process_instance_methods(class_node, class_name, module_name)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 98 def process_instance_methods(class_node, class_name, module_name) class_node.each_instance_method do |instance_method_node| instance_method_name = instance_method_node.full_name(module_name, class_name) @locations[instance_method_name] = instance_method_node.line_range end end
process_module(module_node)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 73 def process_module(module_node) module_name = module_node.name module_node.each_class do |class_node| process_class(class_node, module_name) class_node.hide_methods_from_next_round end process_class(module_node) end
process_singleton_methods(class_node, class_name)
click to toggle source
# File lib/metric_fu/data_structures/line_numbers.rb, line 89 def process_singleton_methods(class_node, class_name) class_node.each_singleton_class do |singleton_node| singleton_node.each_singleton_method do |singleton_method_node| singleton_method_name = singleton_method_node.full_name(class_name) @locations[singleton_method_name] = singleton_method_node.line_range end end end