module Sord::Resolver

Public Class Methods

builtin_classes() click to toggle source

@return [Array<String>]

# File lib/sord/resolver.rb, line 38
def self.builtin_classes
  # This prints some deprecation warnings, so suppress them
  prev_stderr = $stderr
  $stderr = StringIO.new
  
  major = RUBY_VERSION.split('.').first.to_i
  sorted_set_removed = major >= 3 

  Object.constants
    .reject { |x| sorted_set_removed && x == :SortedSet }
    .select { |x| Object.const_get(x).is_a?(Class) }
    .map(&:to_s)
ensure
  $stderr = prev_stderr
end
clear() click to toggle source

@return [void]

# File lib/sord/resolver.rb, line 19
def self.clear
  @@names_to_paths = nil
end
path_for(name) click to toggle source

@param [String] name @return [String, nil]

# File lib/sord/resolver.rb, line 33
def self.path_for(name)
  paths_for(name).one? ? paths_for(name).first : nil
end
paths_for(name) click to toggle source

@param [String] name @return [Array<String>]

# File lib/sord/resolver.rb, line 25
def self.paths_for(name)
  prepare
  (@@names_to_paths[name.split('::').last] || [])
    .select { |x| x.end_with?(name) }
end
prepare() click to toggle source

@return [void]

# File lib/sord/resolver.rb, line 7
def self.prepare
  # Construct a hash of class names to full paths
  @@names_to_paths ||= YARD::Registry.all(:class)
    .group_by(&:name)
    .map { |k, v| [k.to_s, v.map(&:path)] }
    .to_h
    .merge(builtin_classes.map { |x| [x, [x]] }.to_h) do |k, a, b|
      a | b
    end
end
resolvable?(name, item) click to toggle source

@param [String] name @param [Object] item @return [Boolean]

# File lib/sord/resolver.rb, line 57
def self.resolvable?(name, item)
  current_context = item
  current_context = current_context.parent \
    until current_context.is_a?(YARD::CodeObjects::NamespaceObject)

  # If there is any matching object directly in the heirarchy, this is
  # always true. Ruby can do the resolution.
  unless name.include?('::')
    return true if current_context.path.split('::').include?(name)
  end

  name_parts = name.split('::')

  matching_paths = []

  loop do
    # Try to find that class in this context
    path_followed_context = current_context
    name_parts.each do |name_part|
      path_followed_context = path_followed_context&.child(
        name: name_part, type: [:class, :method, :module]
      )
    end

    # Return true if we found the constant we're looking for here
    matching_paths |= [path_followed_context.path] if path_followed_context

    # Move up one context
    break if current_context.root?
    current_context = current_context.parent
  end

  return (builtin_classes.include?(name) && matching_paths.empty?) ||
    (matching_paths.one? && !builtin_classes.include?(name))
end