class Dudes::Calculator

Public Class Methods

new(code) click to toggle source
# File lib/dudes.rb, line 21
def initialize(code)
  @ast = Fast.ast(code)
end

Public Instance Methods

arrayify() click to toggle source

Lot of chunks of code parsed as (:foo, …) if it is a single statement, or (:begin, (:foo, …), (:bar, …)) if it is several independent statements. Robustly make it an array of nodes

# File lib/dudes.rb, line 15
def arrayify
  type == :begin ? children : [self]
end
call() click to toggle source
# File lib/dudes.rb, line 25
def call
  return [] unless @ast
  @ast.arrayify.map(&method(:calc_class)).compact
end
fast(path) click to toggle source
# File lib/dudes.rb, line 8
def fast(path)
  Fast.search(path, self)
end

Private Instance Methods

calc_class(node) click to toggle source
# File lib/dudes.rb, line 32
def calc_class(node)
  return unless node.type == :class

  name, parent, body = *node
  {
    name: name.children.compact.join(':'),
    methods: body&.arrayify&.map(&method(:calc_method))&.compact || [],
    references: extract_references(body)
  }
end
calc_method(node) click to toggle source
# File lib/dudes.rb, line 49
def calc_method(node)
  return unless node.type == :def

  name, args, body = *node

  return empty_body(name, args) if body.nil?

  {
    name: name,
    args: args.children.count,
    length: count_statements(body.arrayify),
    conditions: count_conditions(body),
  }
end
count_conditions(node) click to toggle source
# File lib/dudes.rb, line 78
def count_conditions(node)
  node.fast('({if case} _)').count
end
count_statements(nodes) click to toggle source

FIXME: This is kinda naive… But maybe appropriate enough

# File lib/dudes.rb, line 74
def count_statements(nodes)
  nodes.sum { |n| n.each_node.count }
end
empty_body(name, args) click to toggle source
# File lib/dudes.rb, line 64
def empty_body(name, args)
  {
    name: name,
    args: args.children.count,
    length: 0,
    conditions: 0,
  }
end
extract_references(node) click to toggle source
# File lib/dudes.rb, line 43
def extract_references(node)
  return [] unless node

  node.fast('(const {nil _} )').map { |n| n.children.compact.join('::') }.sort.uniq
end