Class: RuboCop::Cop::Style::For
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::RuboCop::Cop::AutoCorrector,
::RuboCop::Cop::Base,
::RuboCop::ExcludeLimit,
NodePattern::Macros,
RuboCop::AST::Sexp
|
|
|
Instance Chain:
self,
::RuboCop::Cop::ConfigurableEnforcedStyle,
::RuboCop::Cop::Base,
::RuboCop::Cop::AutocorrectLogic,
::RuboCop::Cop::IgnoredNode,
::RuboCop::Util,
RuboCop::AST::Sexp
|
|
| Inherits: |
RuboCop::Cop::Base
|
| Defined in: | lib/rubocop/cop/style/for.rb |
Overview
Looks for uses of the for keyword or each method. The
preferred alternative is set in the EnforcedStyle configuration
parameter. An each call with a block on a single line is always
allowed.
|
Note
|
each is preferred in idiomatic Ruby because for leaks
its loop variable into the surrounding scope.
|
Constant Summary
-
EACH_LENGTH =
# File 'lib/rubocop/cop/style/for.rb', line 52'each'.length
-
IMPLICIT_PARAMETERS =
# File 'lib/rubocop/cop/style/for.rb', line 55%i[_1 _2 _3 _4 _5 _6 _7 _8 _9 it].to_set.freeze
-
PREFER_EACH =
# File 'lib/rubocop/cop/style/for.rb', line 53'Prefer `each` over `for`.' -
PREFER_FOR =
# File 'lib/rubocop/cop/style/for.rb', line 54'Prefer `for` over `each`.'
::RuboCop::Cop::Base - Inherited
DEPARTMENT_SEVERITIES, EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::ConfigurableEnforcedStyle - Included
Class Attribute Summary
::RuboCop::Cop::AutoCorrector - Extended
::RuboCop::Cop::Base - Inherited
| .gem_requirements, .lint?, | |
| .support_autocorrect? | Returns if class supports autocorrect. |
| .support_multiple_source? | Override if your cop should be called repeatedly for multiple investigations Between calls to |
Class Method Summary
-
.autocorrect_incompatible_with
Style/RedundantBeginremoves thebeginof a block body in the same pass, leaving arescueorensureclause directly in theforbody.
::RuboCop::Cop::Base - Inherited
| .autocorrect_incompatible_with | List of cops that should not try to autocorrect at the same time as this cop. |
| .badge | Naming. |
| .callbacks_needed, .cop_name, .department, | |
| .documentation_url | Returns a url to view this cops documentation online. |
| .exclude_from_registry | Call for abstract Cop classes. |
| .inherited, | |
| .joining_forces | Override and return the Force class(es) you need to join. |
| .match? | Returns true if the cop name or the cop namespace matches any of the given names. |
| .new, | |
| .requires_gem | Register a version requirement for the given gem name. |
| .restrict_on_send | Reserved for Commissioner. |
::RuboCop::ExcludeLimit - Extended
| exclude_limit | Sets up a configuration option to have an exclude limit tracked. |
| transform | |
Instance Attribute Summary
::RuboCop::Cop::ConfigurableEnforcedStyle - Included
::RuboCop::Cop::Base - Inherited
| #active_support_extensions_enabled?, #always_autocorrect?, #config, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #disabled_autocorrect?, | |
| #preview? | Whether the user opted in to unstable behavior, with |
| #processed_source, #project_index, #string_literals_frozen_by_default?, #target_satisfies_all_gem_version_requirements? | |
::RuboCop::Cop::AutocorrectLogic - Included
| #autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?, | |
| #skipped_unsafe_correction_with_disable_uncorrectable? | Whether a correction exists but is skipped because it is unsafe in a safe autocorrect run, while |
| #contextual_autocorrect_held_back? | When LSP is enabled or the |
Instance Method Summary
- #on_block(node) (also: #on_numblock, #on_itblock)
- #on_for(node)
-
#on_itblock(node)
Alias for #on_block.
-
#on_numblock(node)
Alias for #on_block.
-
#convertible_to_each?(node) ⇒ Boolean
private
The loop variable becomes a block parameter, which can only be a local variable, and the body can’t refer to an implicit block parameter (
_1orit) once the block has an explicit one. - #convertible_to_for?(node) ⇒ Boolean private
- #do_end_block_in_collection?(node) ⇒ Boolean private
-
#implicit_parameter?(ref, for_node) ⇒ Boolean
private
Inside a numbered or
itblock,_1anditare local variables rather than method calls. - #implicit_parameter_reference?(ref) ⇒ Boolean private
- #rescue_or_ensure_body?(node) ⇒ Boolean private
- #suspect_enumerable?(node) ⇒ Boolean private
::RuboCop::Cop::ConfigurableEnforcedStyle - Included
::RuboCop::Cop::Base - Inherited
| #add_global_offense | Adds an offense that has no particular location. |
| #add_offense | Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense. |
| #begin_investigation | Called before any investigation. |
| #callbacks_needed | — grouped under the Commissioner heading above. |
| #cop_config | Configuration Helpers. |
| #cop_name, #excluded_file?, | |
| #external_dependency_checksum | This method should be overridden when a cop’s behavior depends on state that lives outside of these locations: |
| #inspect, | |
| #message | Gets called if no message is specified when calling |
| #name | Alias for Base#cop_name. |
| #offenses, | |
| #on_investigation_end | Called after all on_… |
| #on_new_investigation | Called before all on_… |
| #on_other_file | Called instead of all on_… |
| #parse | There should be very limited reasons for a Cop to do it’s own parsing. |
| #parser_engine, | |
| #ready | Called between investigations. |
| #relevant_file?, | |
| #target_gem_version | Returns the version of a gem in the target, by default its locked version (i.e. from Gemfile.lock or gems.locked). |
| #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction, | |
| #callback_argument | Reserved for Cop::Cop. |
| #complete_investigation | Called to complete an investigation. |
| #correct, #covering_disabled_range, #current_corrector, | |
| #current_offense_locations | Reserved for Commissioner: |
| #current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, | |
| #enabled_lines? | A multi-line offense is suppressed by a directive on any line of its range, not only its first line, matching the intuition that the directive is attached to the offending code. |
| #file_name_matches_any?, #find_message, #find_severity, #matches_absolute_include_pattern?, #new_offense, #range_for_original, #range_from_node_or_range, | |
| #reset_investigation | Actually private methods. |
| #suppression_reason | The |
| #use_corrector | |
::RuboCop::Cop::AutocorrectLogic - Included
::RuboCop::Cop::IgnoredNode - Included
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Class Method Details
.autocorrect_incompatible_with
Style/RedundantBegin removes the begin of a block body in the same pass,
leaving a rescue or ensure clause directly in the for body.
Style/ItBlockParameter replaces block parameter references in the body
with it in the same pass, while they become for loop variables.
# File 'lib/rubocop/cop/style/for.rb', line 61
def self.autocorrect_incompatible_with [Style::RedundantBegin, Style::ItBlockParameter] end
Instance Method Details
#convertible_to_each?(node) ⇒ Boolean (private)
The loop variable becomes a block parameter, which can only be a local
variable, and the body can’t refer to an implicit block parameter
(_1 or it) once the block has an explicit one.
# File 'lib/rubocop/cop/style/for.rb', line 103
def convertible_to_each?(node) return false unless node.variable.each_node.all? { |n| n.type?(:lvasgn, :mlhs, :splat) } return true unless node.body node.body.each_node(:send, :lvar).none? { |ref| implicit_parameter?(ref, node) } end
#convertible_to_for?(node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/for.rb', line 129
def convertible_to_for?(node) return false if node.type?(:numblock, :itblock) return true unless node.arguments? arguments = node.arguments return false if arguments.children.one? && arguments.children.first.restarg_type? arguments.each_descendant.all? { |arg| arg.type?(:arg, :restarg, :mlhs) } end
#do_end_block_in_collection?(node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/for.rb', line 143
def do_end_block_in_collection?(node) node.receiver.each_node(:any_block).any?(&:keywords?) end
#implicit_parameter?(ref, for_node) ⇒ Boolean (private)
Inside a numbered or it block, _1 and it are local variables
rather than method calls.
# File 'lib/rubocop/cop/style/for.rb', line 112
def implicit_parameter?(ref, for_node) return false unless implicit_parameter_reference?(ref) ref.each_ancestor.take_while { |ancestor| !ancestor.equal?(for_node) } .none?(&:any_block_type?) end
#implicit_parameter_reference?(ref) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/for.rb', line 119
def implicit_parameter_reference?(ref) return IMPLICIT_PARAMETERS.include?(ref.name) if ref.lvar_type? IMPLICIT_PARAMETERS.include?(ref.method_name) && !ref.receiver && !ref.arguments? end
#on_block(node) Also known as: #on_numblock, #on_itblock
[ GitHub ]# File 'lib/rubocop/cop/style/for.rb', line 78
def on_block(node) return unless suspect_enumerable?(node) if style == :for return unless node.receiver return unless convertible_to_for?(node) return if rescue_or_ensure_body?(node) || do_end_block_in_collection?(node) add_offense(node, message: PREFER_FOR) do |corrector| EachToForCorrector.new(node).call(corrector) opposite_style_detected end else correct_style_detected end end
#on_for(node)
[ GitHub ]# File 'lib/rubocop/cop/style/for.rb', line 65
def on_for(node) if style == :each add_offense(node, message: PREFER_EACH) do |corrector| opposite_style_detected next unless convertible_to_each?(node) ForToEachCorrector.new(node).call(corrector) end else correct_style_detected end end
#on_itblock(node)
Alias for #on_block.
# File 'lib/rubocop/cop/style/for.rb', line 96
alias on_itblock on_block
#on_numblock(node)
Alias for #on_block.
# File 'lib/rubocop/cop/style/for.rb', line 95
alias on_numblock on_block
#rescue_or_ensure_body?(node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/for.rb', line 139
def rescue_or_ensure_body?(node) node.body&.type?(:rescue, :ensure) end
#suspect_enumerable?(node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/style/for.rb', line 125
def suspect_enumerable?(node) node.multiline? && node.method?(:each) && !node.send_node.arguments? end