module Mirrors::PackageInference

Constants

APPLICATION_PACKAGE
CORE

ruby –disable-gems -e 'puts Object.constants'

CORE_PACKAGE
CORE_STDLIB_PACKAGE
GEM_PACKAGE_PREFIX
UNKNOWN_EVAL_PACKAGE
UNKNOWN_PACKAGE

Public Instance Methods

contents_of_package(pkg) click to toggle source
# File lib/mirrors/package_inference.rb, line 19
def contents_of_package(pkg)
  @inverse_cache[pkg]
end
infer_from(mod, resolver = ClassToFileResolver.new) click to toggle source
# File lib/mirrors/package_inference.rb, line 11
def infer_from(mod, resolver = ClassToFileResolver.new)
  infer_from_key(Mirrors.module_instance_invoke(mod, :inspect), resolver)
end
infer_from_toplevel(sym, resolver = ClassToFileResolver.new) click to toggle source
# File lib/mirrors/package_inference.rb, line 15
def infer_from_toplevel(sym, resolver = ClassToFileResolver.new)
  infer_from_key(sym.to_s, resolver)
end
qualified_packages() click to toggle source
# File lib/mirrors/package_inference.rb, line 23
def qualified_packages
  @inverse_cache.keys
end

Private Instance Methods

bundle_path() click to toggle source
# File lib/mirrors/package_inference.rb, line 157
def bundle_path
  @bundle_path ||= "#{Bundler.bundle_path}/bundler/gems/"
end
determine_filename(key, resolver) click to toggle source
# File lib/mirrors/package_inference.rb, line 123
def determine_filename(key, resolver)
  resolver.resolve(Object.const_get(key))
end
gem_path() click to toggle source
# File lib/mirrors/package_inference.rb, line 153
def gem_path
  @gem_path ||= Gem.path.map { |p| "#{p}/gems/" }
end
infer_from_key(key, resolver) click to toggle source
# File lib/mirrors/package_inference.rb, line 29
def infer_from_key(key, resolver)
  @inference_cache ||= {}
  @inverse_cache ||= {}

  cached = @inference_cache[key]
  return cached if cached

  pkg = uncached_infer_from(key, [], resolver)
  @inference_cache[key] = pkg
  @inverse_cache[pkg] ||= []
  @inverse_cache[pkg] << key

  pkg
end
nesting_first(n) click to toggle source
# File lib/mirrors/package_inference.rb, line 145
def nesting_first(n)
  n.sub(/::.*/, '')
end
rubylibdir() click to toggle source
# File lib/mirrors/package_inference.rb, line 149
def rubylibdir
  @rubylibdir ||= RbConfig::CONFIG['rubylibdir']
end
try_bundler(filename) click to toggle source
# File lib/mirrors/package_inference.rb, line 110
def try_bundler(filename)
  if defined?(Bundler)
    path = bundle_path
    if filename.start_with?(path)
      gem_with_version = filename[path.size..-1].sub(%r{/.*}, '')
      if gem_with_version =~ /(.*)-(\d|[a-f0-9]+$)/
        return GEM_PACKAGE_PREFIX + $1
      end
    end
  end
  nil
end
try_harder(key, exclusions, resolver) click to toggle source
# File lib/mirrors/package_inference.rb, line 127
def try_harder(key, exclusions, resolver)
  obj = Object.const_get(key)
  return 'obj-not-module' unless obj.is_a?(Module)
  exclusions << obj

  obj.constants.each do |const|
    child = obj.const_get(const)
    next unless child.is_a?(Module)

    next if exclusions.include?(child)

    pkg = uncached_infer_from(Mirrors.module_instance_invoke(child, :inspect), exclusions, resolver)
    return pkg unless pkg == 'unknown'
  end

  return 'unknown'
end
try_rubygems(filename) click to toggle source
# File lib/mirrors/package_inference.rb, line 96
def try_rubygems(filename)
  if defined?(Gem)
    gem_path.each do |path|
      next unless filename.start_with?(path)
      # extract e.g. 'bundler-1.13.6'
      gem_with_version = filename[path.size..-1].sub(%r{/.*}, '')
      if gem_with_version =~ /(.*)-(\d|[a-f0-9]+$)/
        return GEM_PACKAGE_PREFIX + $1
      end
    end
  end
  nil
end
uncached_infer_from(key, exclusions, resolver) click to toggle source
# File lib/mirrors/package_inference.rb, line 71
def uncached_infer_from(key, exclusions, resolver)
  return CORE_PACKAGE if CORE.include?(nesting_first(key))

  filename = determine_filename(key, resolver)

  if filename.nil?
    return try_harder(key, exclusions, resolver)
  end

  return APPLICATION_PACKAGE if filename.start_with?(Mirrors.project_root)
  return CORE_STDLIB_PACKAGE if filename.start_with?(rubylibdir)

  if pkg = try_rubygems(filename)
    return pkg
  end

  if pkg = try_bundler(filename)
    return pkg
  end

  return UNKNOWN_EVAL_PACKAGE if filename == '(eval)'

  UNKNOWN_PACKAGE
end