rubocop 0.73.0 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/console +1 -0
  4. data/config/default.yml +2 -1
  5. data/lib/rubocop.rb +3 -0
  6. data/lib/rubocop/ast/node.rb +1 -7
  7. data/lib/rubocop/config.rb +17 -537
  8. data/lib/rubocop/config_obsoletion.rb +201 -0
  9. data/lib/rubocop/config_validator.rb +239 -0
  10. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -53
  11. data/lib/rubocop/cop/layout/indentation_width.rb +19 -5
  12. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  13. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +22 -40
  14. data/lib/rubocop/cop/lint/debugger.rb +0 -2
  15. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  16. data/lib/rubocop/cop/lint/erb_new_arguments.rb +56 -0
  17. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  18. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  19. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +6 -1
  20. data/lib/rubocop/cop/metrics/line_length.rb +6 -0
  21. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  22. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  23. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  24. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  25. data/lib/rubocop/cop/style/commented_keyword.rb +8 -28
  26. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -3
  27. data/lib/rubocop/cop/style/constant_visibility.rb +13 -2
  28. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  29. data/lib/rubocop/cop/style/lambda.rb +0 -2
  30. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  31. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  32. data/lib/rubocop/path_util.rb +1 -1
  33. data/lib/rubocop/processed_source.rb +4 -0
  34. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  35. data/lib/rubocop/version.rb +1 -1
  36. metadata +5 -2
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # This class handles obsolete configuration.
5
+ class ConfigObsoletion
6
+ RENAMED_COPS = {
7
+ 'Style/SingleSpaceBeforeFirstArg' => 'Layout/SpaceBeforeFirstArg',
8
+ 'Style/MethodCallParentheses' => 'Style/MethodCallWithoutArgsParentheses',
9
+ 'Style/DeprecatedHashMethods' => 'Style/PreferredHashMethods',
10
+ 'Style/OpMethod' => 'Naming/BinaryOperatorParameterName',
11
+ 'Layout/FirstParameterIndentation' => 'Layout/IndentFirstArgument',
12
+ 'Layout/IndentArray' => 'Layout/IndentFirstArrayElement',
13
+ 'Layout/IndentHash' => 'Layout/IndentFirstHashElement'
14
+ }.map do |old_name, new_name|
15
+ [old_name, "The `#{old_name}` cop has been renamed to `#{new_name}`."]
16
+ end
17
+
18
+ MOVED_COPS = {
19
+ 'Security' => 'Lint/Eval',
20
+ 'Naming' => %w[Style/ClassAndModuleCamelCase Style/ConstantName
21
+ Style/FileName Style/MethodName Style/PredicateName
22
+ Style/VariableName Style/VariableNumber
23
+ Style/AccessorMethodName Style/AsciiIdentifiers],
24
+ 'Layout' => %w[Lint/BlockAlignment Lint/EndAlignment
25
+ Lint/DefEndAlignment],
26
+ 'Lint' => 'Style/FlipFlop'
27
+ }.map do |new_department, old_names|
28
+ Array(old_names).map do |old_name|
29
+ [old_name, "The `#{old_name}` cop has been moved to " \
30
+ "`#{new_department}/#{old_name.split('/').last}`."]
31
+ end
32
+ end
33
+
34
+ REMOVED_COPS = {
35
+ 'Rails/DefaultScope' => nil,
36
+ 'Layout/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
37
+ 'Layout/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
38
+ 'Style/SpaceAfterControlKeyword' => 'Layout/SpaceAroundKeyword',
39
+ 'Style/SpaceBeforeModifierKeyword' => 'Layout/SpaceAroundKeyword',
40
+ 'Style/TrailingComma' => 'Style/TrailingCommaInArguments, ' \
41
+ 'Style/TrailingCommaInArrayLiteral, and/or ' \
42
+ 'Style/TrailingCommaInHashLiteral',
43
+ 'Style/TrailingCommaInLiteral' => 'Style/TrailingCommaInArrayLiteral ' \
44
+ 'and/or ' \
45
+ 'Style/TrailingCommaInHashLiteral',
46
+ 'Lint/RescueWithoutErrorClass' => 'Style/RescueStandardError'
47
+ }.map do |old_name, other_cops|
48
+ if other_cops
49
+ more = ". Please use #{other_cops} instead".gsub(%r{[A-Z]\w+/\w+},
50
+ '`\&`')
51
+ end
52
+ [old_name, "The `#{old_name}` cop has been removed#{more}."]
53
+ end
54
+
55
+ REMOVED_COPS_WITH_REASON = {
56
+ 'Lint/InvalidCharacterLiteral' => 'it was never being actually triggered',
57
+ 'Lint/SpaceBeforeFirstArg' =>
58
+ 'it was a duplicate of `Layout/SpaceBeforeFirstArg`. Please use ' \
59
+ '`Layout/SpaceBeforeFirstArg` instead'
60
+ }.map do |cop_name, reason|
61
+ [cop_name, "The `#{cop_name}` cop has been removed since #{reason}."]
62
+ end
63
+
64
+ SPLIT_COPS = {
65
+ 'Style/MethodMissing' =>
66
+ 'The `Style/MethodMissing` cop has been split into ' \
67
+ '`Style/MethodMissingSuper` and `Style/MissingRespondToMissing`.'
68
+ }.to_a
69
+
70
+ OBSOLETE_COPS = Hash[*(RENAMED_COPS + MOVED_COPS + REMOVED_COPS +
71
+ REMOVED_COPS_WITH_REASON + SPLIT_COPS).flatten]
72
+
73
+ OBSOLETE_PARAMETERS = [
74
+ {
75
+ cops: %w[Layout/SpaceAroundOperators Style/SpaceAroundOperators],
76
+ parameters: 'MultiSpaceAllowedForOperators',
77
+ alternative: 'If your intention was to allow extra spaces for ' \
78
+ 'alignment, please use AllowForAlignment: true instead.'
79
+ },
80
+ {
81
+ cops: 'Style/Encoding',
82
+ parameters: %w[EnforcedStyle SupportedStyles
83
+ AutoCorrectEncodingComment],
84
+ alternative: 'Style/Encoding no longer supports styles. ' \
85
+ 'The "never" behavior is always assumed.'
86
+ },
87
+ {
88
+ cops: 'Style/IfUnlessModifier',
89
+ parameters: 'MaxLineLength',
90
+ alternative: '`Style/IfUnlessModifier: MaxLineLength` has been ' \
91
+ 'removed. Use `Metrics/LineLength: Max` instead'
92
+ },
93
+ {
94
+ cops: 'Style/WhileUntilModifier',
95
+ parameters: 'MaxLineLength',
96
+ alternative: '`Style/WhileUntilModifier: MaxLineLength` has been ' \
97
+ 'removed. Use `Metrics/LineLength: Max` instead'
98
+ },
99
+ {
100
+ cops: 'AllCops',
101
+ parameters: 'RunRailsCops',
102
+ alternative: "Use the following configuration instead:\n" \
103
+ "Rails:\n Enabled: true"
104
+ },
105
+ {
106
+ cops: 'Layout/CaseIndentation',
107
+ parameters: 'IndentWhenRelativeTo',
108
+ alternative: '`IndentWhenRelativeTo` has been renamed to ' \
109
+ '`EnforcedStyle`'
110
+ },
111
+ {
112
+ cops: %w[Lint/BlockAlignment Layout/BlockAlignment Lint/EndAlignment
113
+ Layout/EndAlignment Lint/DefEndAlignment
114
+ Layout/DefEndAlignment],
115
+ parameters: 'AlignWith',
116
+ alternative: '`AlignWith` has been renamed to `EnforcedStyleAlignWith`'
117
+ },
118
+ {
119
+ cops: 'Rails/UniqBeforePluck',
120
+ parameters: 'EnforcedMode',
121
+ alternative: '`EnforcedMode` has been renamed to `EnforcedStyle`'
122
+ }
123
+ ].freeze
124
+
125
+ OBSOLETE_ENFORCED_STYLES = [
126
+ {
127
+ cop: 'Layout/IndentationConsistency',
128
+ parameter: 'EnforcedStyle',
129
+ enforced_style: 'rails',
130
+ alternative: '`EnforcedStyle: rails` has been renamed to ' \
131
+ '`EnforcedStyle: indented_internal_methods`'
132
+ }
133
+ ].freeze
134
+
135
+ def initialize(config)
136
+ @config = config
137
+ end
138
+
139
+ def reject_obsolete_cops_and_parameters
140
+ messages = [obsolete_cops, obsolete_parameters,
141
+ obsolete_enforced_style].flatten.compact
142
+ return if messages.empty?
143
+
144
+ raise ValidationError, messages.join("\n")
145
+ end
146
+
147
+ private
148
+
149
+ def obsolete_cops
150
+ OBSOLETE_COPS.map do |cop_name, message|
151
+ next unless @config.key?(cop_name) ||
152
+ @config.key?(Cop::Badge.parse(cop_name).cop_name)
153
+
154
+ message + "\n(obsolete configuration found in " \
155
+ "#{smart_loaded_path}, please update it)"
156
+ end
157
+ end
158
+
159
+ def obsolete_enforced_style
160
+ OBSOLETE_ENFORCED_STYLES.map do |params|
161
+ obsolete_enforced_style_message(params[:cop], params[:parameter],
162
+ params[:enforced_style],
163
+ params[:alternative])
164
+ end
165
+ end
166
+
167
+ def obsolete_enforced_style_message(cop, param, enforced_style, alternative)
168
+ style = @config[cop]&.detect { |key, _| key.start_with?(param) }
169
+
170
+ return unless style && style[1] == enforced_style
171
+
172
+ "obsolete `#{param}: #{enforced_style}` (for #{cop}) found in " \
173
+ "#{smart_loaded_path}\n#{alternative}"
174
+ end
175
+
176
+ def obsolete_parameters
177
+ OBSOLETE_PARAMETERS.map do |params|
178
+ obsolete_parameter_message(params[:cops], params[:parameters],
179
+ params[:alternative])
180
+ end
181
+ end
182
+
183
+ def obsolete_parameter_message(cops, parameters, alternative)
184
+ Array(cops).map do |cop|
185
+ obsolete_parameters = Array(parameters).select do |param|
186
+ @config[cop]&.key?(param)
187
+ end
188
+ next if obsolete_parameters.empty?
189
+
190
+ obsolete_parameters.map do |parameter|
191
+ "obsolete parameter #{parameter} (for #{cop}) found in " \
192
+ "#{smart_loaded_path}\n#{alternative}"
193
+ end
194
+ end
195
+ end
196
+
197
+ def smart_loaded_path
198
+ PathUtil.smart_path(@config.loaded_path)
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module RuboCop
6
+ # Handles validation of configuration, for example cop names, parameter
7
+ # names, and Ruby versions.
8
+ class ConfigValidator
9
+ extend Forwardable
10
+
11
+ COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
12
+ AutoCorrect StyleGuide Details].freeze
13
+ INTERNAL_PARAMS = %w[Description StyleGuide VersionAdded
14
+ VersionChanged Reference Safe SafeAutoCorrect].freeze
15
+
16
+ # 2.3 is the oldest officially supported Ruby version.
17
+ DEFAULT_RUBY_VERSION = 2.3
18
+ KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
19
+ OBSOLETE_RUBIES = {
20
+ 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
21
+ }.freeze
22
+ RUBY_VERSION_FILENAME = '.ruby-version'
23
+
24
+ def_delegators :@config,
25
+ :smart_loaded_path, :for_all_cops, :find_file_upwards,
26
+ :base_dir_for_path_parameters, :bundler_lock_file_path
27
+
28
+ def initialize(config)
29
+ @config = config
30
+ @config_obsoletion = ConfigObsoletion.new(config)
31
+ end
32
+
33
+ def validate
34
+ # Don't validate RuboCop's own files. Avoids infinite recursion.
35
+ base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
36
+ 'config'))
37
+ return if File.expand_path(@config.loaded_path)
38
+ .start_with?(base_config_path)
39
+
40
+ valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
41
+ ConfigLoader.default_configuration.key?(key)
42
+ end
43
+
44
+ @config_obsoletion.reject_obsolete_cops_and_parameters
45
+
46
+ warn_about_unrecognized_cops(invalid_cop_names)
47
+ check_target_ruby
48
+ validate_parameter_names(valid_cop_names)
49
+ validate_enforced_styles(valid_cop_names)
50
+ validate_syntax_cop
51
+ reject_mutually_exclusive_defaults
52
+ end
53
+
54
+ def target_ruby_version
55
+ @target_ruby_version ||= begin
56
+ if for_all_cops['TargetRubyVersion']
57
+ @target_ruby_version_source = :rubocop_yml
58
+
59
+ for_all_cops['TargetRubyVersion'].to_f
60
+ elsif target_ruby_version_from_version_file
61
+ @target_ruby_version_source = :ruby_version_file
62
+
63
+ target_ruby_version_from_version_file
64
+ elsif target_ruby_version_from_bundler_lock_file
65
+ @target_ruby_version_source = :bundler_lock_file
66
+
67
+ target_ruby_version_from_bundler_lock_file
68
+ else
69
+ DEFAULT_RUBY_VERSION
70
+ end
71
+ end
72
+ end
73
+
74
+ def validate_section_presence(name)
75
+ return unless @config.key?(name) && @config[name].nil?
76
+
77
+ raise ValidationError,
78
+ "empty section #{name} found in #{smart_loaded_path}"
79
+ end
80
+
81
+ private
82
+
83
+ def check_target_ruby
84
+ return if KNOWN_RUBIES.include?(target_ruby_version)
85
+
86
+ msg = if OBSOLETE_RUBIES.include?(target_ruby_version)
87
+ "RuboCop found unsupported Ruby version #{target_ruby_version} " \
88
+ "in #{target_ruby_source}. #{target_ruby_version}-compatible " \
89
+ 'analysis was dropped after version ' \
90
+ "#{OBSOLETE_RUBIES[target_ruby_version]}."
91
+ else
92
+ 'RuboCop found unknown Ruby version ' \
93
+ "#{target_ruby_version.inspect} in #{target_ruby_source}."
94
+ end
95
+
96
+ msg += "\nSupported versions: #{KNOWN_RUBIES.join(', ')}"
97
+
98
+ raise ValidationError, msg
99
+ end
100
+
101
+ def warn_about_unrecognized_cops(invalid_cop_names)
102
+ invalid_cop_names.each do |name|
103
+ # There could be a custom cop with this name. If so, don't warn
104
+ next if Cop::Cop.registry.contains_cop_matching?([name])
105
+
106
+ # Special case for inherit_mode, which is a directive that we keep in
107
+ # the configuration (even though it's not a cop), because it's easier
108
+ # to do so than to pass the value around to various methods.
109
+ next if name == 'inherit_mode'
110
+
111
+ warn Rainbow("Warning: unrecognized cop #{name} found in " \
112
+ "#{smart_loaded_path}").yellow
113
+ end
114
+ end
115
+
116
+ def validate_syntax_cop
117
+ syntax_config = @config['Lint/Syntax']
118
+ default_config = ConfigLoader.default_configuration['Lint/Syntax']
119
+
120
+ return unless syntax_config &&
121
+ default_config.merge(syntax_config) != default_config
122
+
123
+ raise ValidationError,
124
+ "configuration for Syntax cop found in #{smart_loaded_path}\n" \
125
+ 'It\'s not possible to disable this cop.'
126
+ end
127
+
128
+ def validate_parameter_names(valid_cop_names)
129
+ valid_cop_names.each do |name|
130
+ validate_section_presence(name)
131
+ default_config = ConfigLoader.default_configuration[name]
132
+
133
+ @config[name].each_key do |param|
134
+ next if COMMON_PARAMS.include?(param) || default_config.key?(param)
135
+
136
+ message =
137
+ "Warning: #{name} does not support #{param} parameter.\n\n" \
138
+ "Supported parameters are:\n\n" \
139
+ " - #{(default_config.keys - INTERNAL_PARAMS).join("\n - ")}\n"
140
+
141
+ warn Rainbow(message).yellow.to_s
142
+ end
143
+ end
144
+ end
145
+
146
+ def validate_enforced_styles(valid_cop_names)
147
+ valid_cop_names.each do |name|
148
+ styles = @config[name].select { |key, _| key.start_with?('Enforced') }
149
+
150
+ styles.each do |style_name, style|
151
+ supported_key = RuboCop::Cop::Util.to_supported_styles(style_name)
152
+ valid = ConfigLoader.default_configuration[name][supported_key]
153
+
154
+ next unless valid
155
+ next if valid.include?(style)
156
+ next if validate_support_and_has_list(name, style, valid)
157
+
158
+ msg = "invalid #{style_name} '#{style}' for #{name} found in " \
159
+ "#{smart_loaded_path}\n" \
160
+ "Valid choices are: #{valid.join(', ')}"
161
+ raise ValidationError, msg
162
+ end
163
+ end
164
+ end
165
+
166
+ def validate_support_and_has_list(name, formats, valid)
167
+ ConfigLoader.default_configuration[name]['AllowMultipleStyles'] &&
168
+ formats.is_a?(Array) &&
169
+ formats.all? { |format| valid.include?(format) }
170
+ end
171
+
172
+ def target_ruby_source
173
+ case @target_ruby_version_source
174
+ when :ruby_version_file
175
+ "`#{RUBY_VERSION_FILENAME}`"
176
+ when :bundler_lock_file
177
+ "`#{bundler_lock_file_path}`"
178
+ when :rubocop_yml
179
+ "`TargetRubyVersion` parameter (in #{smart_loaded_path})"
180
+ end
181
+ end
182
+
183
+ def ruby_version_file
184
+ @ruby_version_file ||=
185
+ find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
186
+ end
187
+
188
+ def target_ruby_version_from_version_file
189
+ file = ruby_version_file
190
+ return unless file && File.file?(file)
191
+
192
+ @target_ruby_version_from_version_file ||=
193
+ File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
194
+ md[:version].to_f
195
+ end
196
+ end
197
+
198
+ def target_ruby_version_from_bundler_lock_file
199
+ @target_ruby_version_from_bundler_lock_file ||=
200
+ read_ruby_version_from_bundler_lock_file
201
+ end
202
+
203
+ def read_ruby_version_from_bundler_lock_file
204
+ lock_file_path = bundler_lock_file_path
205
+ return nil unless lock_file_path
206
+
207
+ in_ruby_section = false
208
+ File.foreach(lock_file_path) do |line|
209
+ # If ruby is in Gemfile.lock or gems.lock, there should be two lines
210
+ # towards the bottom of the file that look like:
211
+ # RUBY VERSION
212
+ # ruby W.X.YpZ
213
+ # We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
214
+ # extra logic to make sure we only start looking once we've seen the
215
+ # "RUBY VERSION" line.
216
+ in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
217
+ next unless in_ruby_section
218
+
219
+ # We currently only allow this feature to work with MRI ruby. If jruby
220
+ # (or something else) is used by the project, it's lock file will have a
221
+ # line that looks like:
222
+ # RUBY VERSION
223
+ # ruby W.X.YpZ (jruby x.x.x.x)
224
+ # The regex won't match in this situation.
225
+ result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
226
+ return result.captures.first.to_f if result
227
+ end
228
+ end
229
+
230
+ def reject_mutually_exclusive_defaults
231
+ disabled_by_default = for_all_cops['DisabledByDefault']
232
+ enabled_by_default = for_all_cops['EnabledByDefault']
233
+ return unless disabled_by_default && enabled_by_default
234
+
235
+ msg = 'Cops cannot be both enabled by default and disabled by default'
236
+ raise ValidationError, msg
237
+ end
238
+ end
239
+ end
@@ -41,12 +41,7 @@ module RuboCop
41
41
  def investigate(processed_source)
42
42
  return if processed_source.blank?
43
43
 
44
- if force_equal_sign_alignment?
45
- @asgn_tokens = assignment_tokens
46
- @asgn_lines = @asgn_tokens.map(&:line)
47
- # Don't attempt to correct the same = more than once
48
- @corrected = Set.new
49
- end
44
+ @corrected = Set.new if force_equal_sign_alignment?
50
45
 
51
46
  processed_source.tokens.each_cons(2) do |token1, token2|
52
47
  check_tokens(processed_source.ast, token1, token2)
@@ -65,24 +60,10 @@ module RuboCop
65
60
 
66
61
  private
67
62
 
68
- def assignment_tokens
69
- tokens = processed_source.tokens.select(&:equal_sign?)
70
- # we don't want to operate on equals signs which are part of an
71
- # optarg in a method definition
72
- # e.g.: def method(optarg = default_val); end
73
- tokens = remove_optarg_equals(tokens, processed_source)
74
-
75
- # Only attempt to align the first = on each line
76
- Set.new(tokens.uniq(&:line))
77
- end
78
-
79
63
  def check_tokens(ast, token1, token2)
80
64
  return if token2.type == :tNL
81
65
 
82
- if force_equal_sign_alignment? &&
83
- @asgn_tokens.include?(token2) &&
84
- (@asgn_lines.include?(token2.line - 1) ||
85
- @asgn_lines.include?(token2.line + 1))
66
+ if force_equal_sign_alignment? && assignment_tokens.include?(token2)
86
67
  check_assignment(token2)
87
68
  else
88
69
  check_other(token1, token2, ast)
@@ -90,24 +71,12 @@ module RuboCop
90
71
  end
91
72
 
92
73
  def check_assignment(token)
93
- assignment_line = ''
94
- message = ''
95
- if should_aligned_with_preceding_line?(token)
96
- assignment_line = processed_source.preceding_line(token)
97
- message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
98
- else
99
- assignment_line = processed_source.following_line(token)
100
- message = format(MSG_UNALIGNED_ASGN, location: 'following')
101
- end
102
- return if aligned_assignment?(token.pos, assignment_line)
74
+ return unless aligned_with_preceding_assignment(token) == :no
103
75
 
76
+ message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
104
77
  add_offense(token.pos, location: token.pos, message: message)
105
78
  end
106
79
 
107
- def should_aligned_with_preceding_line?(token)
108
- @asgn_lines.include?(token.line - 1)
109
- end
110
-
111
80
  def check_other(token1, token2, ast)
112
81
  return false if allow_for_trailing_comments? &&
113
82
  token2.text.start_with?('#')
@@ -188,8 +157,8 @@ module RuboCop
188
157
  end
189
158
 
190
159
  def align_equal_signs(range, corrector)
191
- lines = contiguous_assignment_lines(range)
192
- tokens = @asgn_tokens.select { |t| lines.include?(t.line) }
160
+ lines = all_relevant_assignment_lines(range.line)
161
+ tokens = assignment_tokens.select { |t| lines.include?(t.line) }
193
162
 
194
163
  columns = tokens.map { |t| align_column(t) }
195
164
  align_to = columns.max
@@ -209,17 +178,15 @@ module RuboCop
209
178
  end
210
179
  end
211
180
 
212
- def contiguous_assignment_lines(range)
213
- result = [range.line]
214
-
215
- range.line.downto(1) do |lineno|
216
- @asgn_lines.include?(lineno) ? result << lineno : break
217
- end
218
- range.line.upto(processed_source.lines.size) do |lineno|
219
- @asgn_lines.include?(lineno) ? result << lineno : break
220
- end
181
+ def all_relevant_assignment_lines(line_number)
182
+ last_line_number = processed_source.lines.size
221
183
 
222
- result.sort!
184
+ (
185
+ relevant_assignment_lines(line_number.downto(1)) +
186
+ relevant_assignment_lines(line_number.upto(last_line_number))
187
+ )
188
+ .uniq
189
+ .sort
223
190
  end
224
191
 
225
192
  def align_column(asgn_token)
@@ -231,12 +198,6 @@ module RuboCop
231
198
  asgn_token.pos.last_column - spaces + 1
232
199
  end
233
200
 
234
- def remove_optarg_equals(asgn_tokens, processed_source)
235
- optargs = processed_source.ast.each_node(:optarg)
236
- optarg_eql = optargs.map { |o| o.loc.operator.begin_pos }.to_set
237
- asgn_tokens.reject { |t| optarg_eql.include?(t.begin_pos) }
238
- end
239
-
240
201
  def allow_for_trailing_comments?
241
202
  cop_config['AllowBeforeTrailingComments']
242
203
  end