module SimpleCov::StaticCoverageExtractor::MethodCollector

def constant_name(node)

simplecov:disable
always carry a constant_path in practice.
string. Defensive nil / to_s fallbacks: ClassNode and ModuleNode
Render a constant path (e.g., `Foo::Bar`) as its source-form
def constant_name(node)
  return "<anonymous>" if node.nil?
  return node.slice if node.respond_to?(:slice)
  node.to_s
end

def visit_class_node(node)

since `Coverage` reports both as the constant.
class name. Module + Class are both treated as namespaces here
Track class/module nesting so method tuples carry the lexical
def visit_class_node(node)
  with_class(constant_name(node.constant_path)) { super }
end

def visit_def_node(node)

`Object` at the top level, matching `Coverage`'s convention).
The class context is the surrounding lexical class/module (or
`def name(...)` and `def self.name(...)` both produce DefNode.
def visit_def_node(node)
  loc = node.location
  class_name = @class_stack.last || "Object"
  key = [class_name, node.name, loc.start_line, loc.start_column, loc.end_line, loc.end_column]
  @methods[key] = 0
  super
end

def visit_module_node(node)

def visit_module_node(node)
  with_class(constant_name(node.constant_path)) { super }
end

def with_class(name)

def with_class(name)
  @class_stack.push(name)
  yield
ensure
  @class_stack.pop
end