Class: RuboCop::Cop::Naming::MemoizedInstanceVariableName
- Extended by:
- AutoCorrector
- Includes:
- ConfigurableEnforcedStyle
- Defined in:
- lib/rubocop/cop/naming/memoized_instance_variable_name.rb
Overview
Checks for memoized methods whose instance variable name
does not match the method name. Applies to both regular methods
(defined with def
) and dynamic methods (defined with
define_method
or define_singleton_method
).
This cop can be configured with the EnforcedStyleForLeadingUnderscores directive. It can be configured to allow for memoized instance variables prefixed with an underscore. Prefixing ivars with an underscore is a convention that is used to implicitly indicate that an ivar should not be set or referenced outside of the memoization method.
Constant Summary collapse
- MSG =
'Memoized variable `%<var>s` does not match ' \ 'method name `%<method>s`. Use `@%<suggested_var>s` instead.'
- UNDERSCORE_REQUIRED =
'Memoized variable `%<var>s` does not start ' \ 'with `_`. Use `@%<suggested_var>s` instead.'
- DYNAMIC_DEFINE_METHODS =
%i[define_method define_singleton_method].to_set.freeze
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #defined_memoized?(node, ivar) ⇒ Object
- #method_definition?(node) ⇒ Object
-
#on_defined?(node) ⇒ Boolean
rubocop:disable Metrics/AbcSize, Metrics/MethodLength.
-
#on_or_asgn(node) ⇒ Object
rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength.
Methods included from AutoCorrector
Methods included from ConfigurableEnforcedStyle
#alternative_style, #alternative_styles, #ambiguous_style_detected, #correct_style_detected, #detected_style, #detected_style=, #no_acceptable_style!, #no_acceptable_style?, #opposite_style_detected, #style, #style_configured?, #style_detected, #supported_styles, #unexpected_style_detected
Methods inherited from Base
#active_support_extensions_enabled?, #add_global_offense, #add_offense, autocorrect_incompatible_with, badge, #begin_investigation, callbacks_needed, #callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #ready, #relevant_file?, support_autocorrect?, support_multiple_source?, #target_rails_version, #target_ruby_version
Methods included from ExcludeLimit
Methods included from AutocorrectLogic
#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?
Methods included from IgnoredNode
#ignore_node, #ignored_node?, #part_of_ignored_node?
Methods included from Util
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Method Details
#defined_memoized?(node, ivar) ⇒ Object
197 198 199 200 201 202 |
# File 'lib/rubocop/cop/naming/memoized_instance_variable_name.rb', line 197 def_node_matcher :defined_memoized?, <<~PATTERN (begin (if (defined $(ivar %1)) (return $(ivar %1)) nil?) ... $(ivasgn %1 _)) PATTERN |
#method_definition?(node) ⇒ Object
160 161 162 163 164 165 166 |
# File 'lib/rubocop/cop/naming/memoized_instance_variable_name.rb', line 160 def_node_matcher :method_definition?, <<~PATTERN ${ (block (send _ %DYNAMIC_DEFINE_METHODS ({sym str} $_)) ...) (def $_ ...) (defs _ $_ ...) } PATTERN |
#on_defined?(node) ⇒ Boolean
rubocop:disable Metrics/AbcSize, Metrics/MethodLength
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/rubocop/cop/naming/memoized_instance_variable_name.rb', line 205 def on_defined?(node) arg = node.arguments.first return false unless arg.ivar_type? method_node, method_name = find_definition(node) return false unless method_node var_name = arg.children.first defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign| return false if matches?(method_name, ivar_assign) suggested_var = suggested_var(method_name) msg = format( (var_name.to_s), var: var_name.to_s, suggested_var: suggested_var, method: method_name ) add_offense(defined_ivar, message: msg) do |corrector| corrector.replace(defined_ivar, "@#{suggested_var}") end add_offense(return_ivar, message: msg) do |corrector| corrector.replace(return_ivar, "@#{suggested_var}") end add_offense(ivar_assign.loc.name, message: msg) do |corrector| corrector.replace(ivar_assign.loc.name, "@#{suggested_var}") end end end |
#on_or_asgn(node) ⇒ Object
rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/rubocop/cop/naming/memoized_instance_variable_name.rb', line 170 def on_or_asgn(node) lhs, _value = *node return unless lhs.ivasgn_type? method_node, method_name = find_definition(node) return unless method_node body = method_node.body return unless body == node || body.children.last == node return if matches?(method_name, lhs) suggested_var = suggested_var(method_name) msg = format( (lhs.children.first.to_s), var: lhs.children.first.to_s, suggested_var: suggested_var, method: method_name ) add_offense(lhs, message: msg) do |corrector| corrector.replace(lhs.loc.name, "@#{suggested_var}") end end |