class Packwerk::ParsedConstantDefinitions

Public Class Methods

new(root_node:) click to toggle source
# File lib/packwerk/parsed_constant_definitions.rb, line 8
def initialize(root_node:)
  @local_definitions = {}

  collect_local_definitions_from_root(root_node) if root_node
end
reference_qualifications(constant_name, namespace_path:) click to toggle source

What fully qualified constants can this constant refer to in this context?

# File lib/packwerk/parsed_constant_definitions.rb, line 24
def self.reference_qualifications(constant_name, namespace_path:)
  return [constant_name] if constant_name.start_with?("::")

  fully_qualified_constant_name = "::#{constant_name}"

  possible_namespaces = namespace_path.each_with_object([""]) do |current, acc|
    acc << "#{acc.last}::#{current}" if acc.last && current
  end

  possible_namespaces.map { |namespace| namespace + fully_qualified_constant_name }
end

Public Instance Methods

local_reference?(constant_name, location: nil, namespace_path: []) click to toggle source
# File lib/packwerk/parsed_constant_definitions.rb, line 14
def local_reference?(constant_name, location: nil, namespace_path: [])
  qualifications = self.class.reference_qualifications(constant_name, namespace_path: namespace_path)

  qualifications.any? do |name|
    @local_definitions[name] &&
      @local_definitions[name] != location
  end
end

Private Instance Methods

add_definition(constant_name, current_namespace_path, location) click to toggle source
# File lib/packwerk/parsed_constant_definitions.rb, line 54
def add_definition(constant_name, current_namespace_path, location)
  fully_qualified_constant = [""].concat(current_namespace_path).push(constant_name).join("::")

  @local_definitions[fully_qualified_constant] = location
end
collect_local_definitions_from_root(node, current_namespace_path = []) click to toggle source
# File lib/packwerk/parsed_constant_definitions.rb, line 38
def collect_local_definitions_from_root(node, current_namespace_path = [])
  if Node.constant_assignment?(node)
    add_definition(Node.constant_name(node), current_namespace_path, Node.name_location(node))
  elsif Node.module_name_from_definition(node)
    # handle compact constant nesting (e.g. "module Sales::Order")
    tempnode = node
    while (tempnode = Node.each_child(tempnode).find { |n| Node.constant?(n) })
      add_definition(Node.constant_name(tempnode), current_namespace_path, Node.name_location(tempnode))
    end

    current_namespace_path += Node.class_or_module_name(node).split("::")
  end

  Node.each_child(node) { |child| collect_local_definitions_from_root(child, current_namespace_path) }
end