Class: RubyLint::ConstantLoader
- Defined in:
- lib/ruby-lint/constant_loader.rb
Overview
The ConstantLoader is an iterator class (using 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
#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.
Constant Summary
- BOOTSTRAP_CONSTS =
Built-in definitions that should be bootstrapped.
%w{Module Class Kernel BasicObject Object}
- BOOTSTRAP_GVARS =
List of global variables that should be bootstrapped.
[ '$!', '$$', '$&', '$\'', '$*', '$+', '$,', '$-0', '$-F', '$-I', '$-K', '$-W', '$-a', '$-d', '$-i', '$-l', '$-p', '$-v', '$-w', '$.', '$/', '$0', '$:', '$;', '$<', '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE', '$LOADED_FEATURES', '$LOAD_PATH', '$PROGRAM_NAME', '$SAFE', '$VERBOSE', '$\"', '$\\', '$_', '$`', '$stderr', '$stdin', '$stdout', '$~' # Regexp $1, $2,... $99 are lazy loaded when first used ]
Instance Attribute Summary collapse
-
#definitions ⇒ RubyLint::Definition::RubyObject
readonly
-
#loaded ⇒ Set
readonly
Set containing the loaded constants.
-
#module_nesting ⇒ Array<String>
readonly
Attributes inherited from Iterator
#arity_cache, #arity_cache Hash containing the amount of arguments for
Instance Method Summary collapse
-
#after_class(_node) ⇒ Object
-
#after_initialize ⇒ Object
Called after a new instance of the class is created.
-
#after_module(_node) ⇒ Object
-
#apply(constant) ⇒ Object
private
-
#bootstrap ⇒ Object
Bootstraps various core definitions.
-
#load_constant(constant) ⇒ Object
Tries to load the definitions for the given constant.
-
#load_nested_constant(constant) ⇒ Object
Tries to load the definitions for the given constant.
-
#loaded?(constant) ⇒ TrueClass|FalseClass
Checks if the given constant is already loaded or not.
-
#on_class(node) ⇒ Object
-
#on_const(node) ⇒ Object
-
#on_module(node) ⇒ Object
-
#registry ⇒ RubyLint::Definition::Registry
-
#run(ast) ⇒ Object
Bootstraps various core definitions (Fixnum, Object, etc) and loads the extra constants referred in the supplied AST.
Methods inherited from Iterator
#execute_callback, #initialize, #iterate, #skip_child_nodes!
Constructor Details
This class inherits a constructor from RubyLint::Iterator
Instance Attribute Details
#definitions ⇒ RubyLint::Definition::RubyObject (readonly)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/ruby-lint/constant_loader.rb', line 22 class ConstantLoader < Iterator attr_reader :loaded, :definitions, :module_nesting ## # Built-in definitions that should be bootstrapped. # # @return [Array] # BOOTSTRAP_CONSTS = %w{Module Class Kernel BasicObject Object} ## # List of global variables that should be bootstrapped. # # @return [Array] # BOOTSTRAP_GVARS = [ '$!', '$$', '$&', '$\'', '$*', '$+', '$,', '$-0', '$-F', '$-I', '$-K', '$-W', '$-a', '$-d', '$-i', '$-l', '$-p', '$-v', '$-w', '$.', '$/', '$0', '$:', '$;', '$<', '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE', '$LOADED_FEATURES', '$LOAD_PATH', '$PROGRAM_NAME', '$SAFE', '$VERBOSE', '$\"', '$\\', '$_', '$`', '$stderr', '$stdin', '$stdout', '$~' # Regexp $1, $2,... $99 are lazy loaded when first used ] ## # Bootstraps various core definitions. # 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 ## # Bootstraps various core definitions (Fixnum, Object, etc) and loads the # extra constants referred in the supplied AST. # # @param [Array<RubyLint::AST::Node>] ast # def run(ast) ast.each { |node| iterate(node) } end ## # Called after a new instance of the class is created. # 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 def on_class(node) name, _parent, _body = *node cp = ConstantPath.new(name) @module_nesting.push(cp.to_s) end def after_class(_node) @module_nesting.pop end ## # @param [RubyLint::Node] node # def on_const(node) load_nested_constant(ConstantPath.new(node).to_s) end ## # Checks if the given constant is already loaded or not. # # @param [String] constant # @return [TrueClass|FalseClass] # def loaded?(constant) return loaded.include?(constant) end ## # @return [RubyLint::Definition::Registry] # 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) 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 ## # Tries to load the definitions for the given constant. # # @param [String] constant # def load_constant(constant) return if loaded?(constant) registry.load(constant) return unless registry.include?(constant) apply(constant) end private ## # @param [String] constant # def apply(constant) loaded << constant registry.apply(constant, definitions) end end |
#loaded ⇒ Set (readonly)
Returns Set containing the loaded constants.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/ruby-lint/constant_loader.rb', line 22 class ConstantLoader < Iterator attr_reader :loaded, :definitions, :module_nesting ## # Built-in definitions that should be bootstrapped. # # @return [Array] # BOOTSTRAP_CONSTS = %w{Module Class Kernel BasicObject Object} ## # List of global variables that should be bootstrapped. # # @return [Array] # BOOTSTRAP_GVARS = [ '$!', '$$', '$&', '$\'', '$*', '$+', '$,', '$-0', '$-F', '$-I', '$-K', '$-W', '$-a', '$-d', '$-i', '$-l', '$-p', '$-v', '$-w', '$.', '$/', '$0', '$:', '$;', '$<', '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE', '$LOADED_FEATURES', '$LOAD_PATH', '$PROGRAM_NAME', '$SAFE', '$VERBOSE', '$\"', '$\\', '$_', '$`', '$stderr', '$stdin', '$stdout', '$~' # Regexp $1, $2,... $99 are lazy loaded when first used ] ## # Bootstraps various core definitions. # 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 ## # Bootstraps various core definitions (Fixnum, Object, etc) and loads the # extra constants referred in the supplied AST. # # @param [Array<RubyLint::AST::Node>] ast # def run(ast) ast.each { |node| iterate(node) } end ## # Called after a new instance of the class is created. # 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 def on_class(node) name, _parent, _body = *node cp = ConstantPath.new(name) @module_nesting.push(cp.to_s) end def after_class(_node) @module_nesting.pop end ## # @param [RubyLint::Node] node # def on_const(node) load_nested_constant(ConstantPath.new(node).to_s) end ## # Checks if the given constant is already loaded or not. # # @param [String] constant # @return [TrueClass|FalseClass] # def loaded?(constant) return loaded.include?(constant) end ## # @return [RubyLint::Definition::Registry] # 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) 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 ## # Tries to load the definitions for the given constant. # # @param [String] constant # def load_constant(constant) return if loaded?(constant) registry.load(constant) return unless registry.include?(constant) apply(constant) end private ## # @param [String] constant # def apply(constant) loaded << constant registry.apply(constant, definitions) end end |
#module_nesting ⇒ Array<String> (readonly)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/ruby-lint/constant_loader.rb', line 22 class ConstantLoader < Iterator attr_reader :loaded, :definitions, :module_nesting ## # Built-in definitions that should be bootstrapped. # # @return [Array] # BOOTSTRAP_CONSTS = %w{Module Class Kernel BasicObject Object} ## # List of global variables that should be bootstrapped. # # @return [Array] # BOOTSTRAP_GVARS = [ '$!', '$$', '$&', '$\'', '$*', '$+', '$,', '$-0', '$-F', '$-I', '$-K', '$-W', '$-a', '$-d', '$-i', '$-l', '$-p', '$-v', '$-w', '$.', '$/', '$0', '$:', '$;', '$<', '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE', '$LOADED_FEATURES', '$LOAD_PATH', '$PROGRAM_NAME', '$SAFE', '$VERBOSE', '$\"', '$\\', '$_', '$`', '$stderr', '$stdin', '$stdout', '$~' # Regexp $1, $2,... $99 are lazy loaded when first used ] ## # Bootstraps various core definitions. # 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 ## # Bootstraps various core definitions (Fixnum, Object, etc) and loads the # extra constants referred in the supplied AST. # # @param [Array<RubyLint::AST::Node>] ast # def run(ast) ast.each { |node| iterate(node) } end ## # Called after a new instance of the class is created. # 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 def on_class(node) name, _parent, _body = *node cp = ConstantPath.new(name) @module_nesting.push(cp.to_s) end def after_class(_node) @module_nesting.pop end ## # @param [RubyLint::Node] node # def on_const(node) load_nested_constant(ConstantPath.new(node).to_s) end ## # Checks if the given constant is already loaded or not. # # @param [String] constant # @return [TrueClass|FalseClass] # def loaded?(constant) return loaded.include?(constant) end ## # @return [RubyLint::Definition::Registry] # 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) 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 ## # Tries to load the definitions for the given constant. # # @param [String] constant # def load_constant(constant) return if loaded?(constant) registry.load(constant) return unless registry.include?(constant) apply(constant) end private ## # @param [String] constant # def apply(constant) loaded << constant registry.apply(constant, definitions) end end |
Instance Method Details
#after_class(_node) ⇒ Object
97 98 99 |
# File 'lib/ruby-lint/constant_loader.rb', line 97 def after_class(_node) @module_nesting.pop end |
#after_initialize ⇒ Object
Called after a new instance of the class is created.
74 75 76 77 |
# File 'lib/ruby-lint/constant_loader.rb', line 74 def after_initialize @loaded = Set.new @module_nesting = [] end |
#after_module(_node) ⇒ Object
86 87 88 |
# File 'lib/ruby-lint/constant_loader.rb', line 86 def after_module(_node) @module_nesting.pop end |
#apply(constant) ⇒ Object (private)
167 168 169 170 171 |
# File 'lib/ruby-lint/constant_loader.rb', line 167 def apply(constant) loaded << constant registry.apply(constant, definitions) end |
#bootstrap ⇒ Object
Bootstraps various core definitions.
49 50 51 52 53 54 55 56 57 58 59 |
# 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) ⇒ Object
Tries to load the definitions for the given constant.
152 153 154 155 156 157 158 159 160 |
# 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) ⇒ Object
Tries to load the definitions for the given constant. Takes into account what modules we are in to resolve the constant name.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# 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) ⇒ TrueClass|FalseClass
Checks if the given constant is already loaded or not.
114 115 116 |
# File 'lib/ruby-lint/constant_loader.rb', line 114 def loaded?(constant) return loaded.include?(constant) end |
#on_class(node) ⇒ Object
90 91 92 93 94 95 |
# 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) ⇒ Object
104 105 106 |
# 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) ⇒ Object
79 80 81 82 83 84 |
# 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 ⇒ RubyLint::Definition::Registry
121 122 123 |
# File 'lib/ruby-lint/constant_loader.rb', line 121 def registry return RubyLint.registry end |
#run(ast) ⇒ Object
Bootstraps various core definitions (Fixnum, Object, etc) and loads the extra constants referred in the supplied AST.
67 68 69 |
# File 'lib/ruby-lint/constant_loader.rb', line 67 def run(ast) ast.each { |node| iterate(node) } end |