Skip to content
This repository has been archived by the owner on Mar 16, 2023. It is now read-only.

Commit

Permalink
Load constant Foo::Bar when Bar is seen inside Foo.
Browse files Browse the repository at this point in the history
  • Loading branch information
mvidner committed Jun 25, 2016
1 parent a535662 commit 3d83ae7
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions lib/ruby-lint/constant_loader.rb
Expand Up @@ -16,8 +16,11 @@ module RubyLint
# @!attribute [r] definitions
# @return [RubyLint::Definition::RubyObject]
#
# @!attribute [r] module_nesting
# @return [Array<String>]
#
class ConstantLoader < Iterator
attr_reader :loaded, :definitions
attr_reader :loaded, :definitions, :module_nesting

##
# Built-in definitions that should be bootstrapped.
Expand Down Expand Up @@ -70,13 +73,26 @@ def run(ast)
#
def after_initialize
@loaded = Set.new
@module_nesting = []
end

def on_module(node)
name, _body = *node
cp = ConstantPath.new(name)

@module_nesting.push(cp.to_s)
end


def after_module(node)
@module_nesting.pop
end

##
# @param [RubyLint::Node] node
#
def on_const(node)
load_constant(ConstantPath.new(node).root_node[1])
load_nested_constant(ConstantPath.new(node).root_node[1])
end

##
Expand All @@ -96,6 +112,24 @@ def registry
return RubyLint.registry
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
#
def load_nested_constant(constant)
# ["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
load_constant(constant)
end

##
# Tries to load the definitions for the given constant.
#
Expand Down

0 comments on commit 3d83ae7

Please sign in to comment.