class RubyLint::ConstantLoader

The ConstantLoader is an iterator class (using {RubyLint::Iterator}) that iterates over an AST and tries to load the corresponding built-in definitions. For example, if it finds a constant node for the `ERB` class it will apply the definitions for `ERB` to the ones set in {RubyLint::ConstantLoader#definitions}.

This class also takes care of bootstrapping the target definitions so that the bare minimum definitions (e.g. Module and Object) are always available. Global variables are also bootstrapped.

@!attribute [r] loaded

@return [Set] Set containing the loaded constants.

@!attribute [r] definitions

@return [RubyLint::Definition::RubyObject]

@!attribute [r] module_nesting

@return [Array<String>]

Constants

BOOTSTRAP_CONSTS

Built-in definitions that should be bootstrapped.

@return [Array]

BOOTSTRAP_GVARS

List of global variables that should be bootstrapped.

@return [Array]

Attributes

definitions[R]
loaded[R]
module_nesting[R]

Public Instance Methods

after_class(_node) click to toggle source
# File lib/ruby-lint/constant_loader.rb, line 97
def after_class(_node)
  @module_nesting.pop
end
after_initialize() click to toggle source

Called after a new instance of the class is created.

# File lib/ruby-lint/constant_loader.rb, line 74
def after_initialize
  @loaded = Set.new
  @module_nesting = []
end
after_module(_node) click to toggle source
# File lib/ruby-lint/constant_loader.rb, line 86
def after_module(_node)
  @module_nesting.pop
end
bootstrap() click to toggle source

Bootstraps various core definitions.

# File lib/ruby-lint/constant_loader.rb, line 49
def bootstrap
  types = VariablePredicates::RUBY_CLASSES.values

  (BOOTSTRAP_CONSTS | types).each do |name|
    load_constant(name)
  end

  BOOTSTRAP_GVARS.each do |gvar|
    definitions.define_global_variable(gvar)
  end
end
load_constant(constant) click to toggle source

Tries to load the definitions for the given constant.

@param [String] constant

# File lib/ruby-lint/constant_loader.rb, line 152
def load_constant(constant)
  return if loaded?(constant)

  registry.load(constant)

  return unless registry.include?(constant)

  apply(constant)
end
load_nested_constant(constant) click to toggle source

Tries to load the definitions for the given constant. Takes into account what modules we are in to resolve the constant name.

@param [String] constant name, possibly unqualified

# File lib/ruby-lint/constant_loader.rb, line 131
def load_nested_constant(constant)
  if constant.start_with?("::")
    constant = constant.sub(/^::/, "")
  else
    # ["A", "B", "C"] -> ["A::B::C", "A::B", "A"]
    namespaces = module_nesting.size.downto(1).map do |n|
      module_nesting.take(n).join("::")
    end

    namespaces.each do |ns|
      load_constant("#{ns}::#{constant}")
    end
  end
  load_constant(constant)
end
loaded?(constant) click to toggle source

Checks if the given constant is already loaded or not.

@param [String] constant @return [TrueClass|FalseClass]

# File lib/ruby-lint/constant_loader.rb, line 114
def loaded?(constant)
  return loaded.include?(constant)
end
on_class(node) click to toggle source
# File lib/ruby-lint/constant_loader.rb, line 90
def on_class(node)
  name, _parent, _body = *node
  cp = ConstantPath.new(name)

  @module_nesting.push(cp.to_s)
end
on_const(node) click to toggle source

@param [RubyLint::Node] node

# File lib/ruby-lint/constant_loader.rb, line 104
def on_const(node)
  load_nested_constant(ConstantPath.new(node).to_s)
end
on_module(node) click to toggle source
# File lib/ruby-lint/constant_loader.rb, line 79
def on_module(node)
  name, _body = *node
  cp = ConstantPath.new(name)

  @module_nesting.push(cp.to_s)
end
registry() click to toggle source

@return [RubyLint::Definition::Registry]

# File lib/ruby-lint/constant_loader.rb, line 121
def registry
  return RubyLint.registry
end
run(ast) click to toggle source

Bootstraps various core definitions (Fixnum, Object, etc) and loads the extra constants referred in the supplied AST.

@param [Array<RubyLint::AST::Node>] ast

# File lib/ruby-lint/constant_loader.rb, line 67
def run(ast)
  ast.each { |node| iterate(node) }
end

Private Instance Methods

apply(constant) click to toggle source

@param [String] constant

# File lib/ruby-lint/constant_loader.rb, line 167
def apply(constant)
  loaded << constant

  registry.apply(constant, definitions)
end