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
Public Instance Methods
# File lib/ruby-lint/constant_loader.rb, line 97 def after_class(_node) @module_nesting.pop end
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
# File lib/ruby-lint/constant_loader.rb, line 86 def after_module(_node) @module_nesting.pop end
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
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
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
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
# 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
@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
# 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
@return [RubyLint::Definition::Registry]
# File lib/ruby-lint/constant_loader.rb, line 121 def registry return RubyLint.registry end
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
@param [String] constant
# File lib/ruby-lint/constant_loader.rb, line 167 def apply(constant) loaded << constant registry.apply(constant, definitions) end