rubocop 0.52.0 → 0.52.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -5
- data/config/default.yml +1 -11
- data/config/disabled.yml +5 -0
- data/config/enabled.yml +6 -8
- data/lib/rubocop.rb +13 -2
- data/lib/rubocop/ast/node.rb +23 -15
- data/lib/rubocop/cli.rb +25 -2
- data/lib/rubocop/config.rb +23 -8
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -0
- data/lib/rubocop/cop/commissioner.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +121 -0
- data/lib/rubocop/cop/correctors/condition_corrector.rb +28 -0
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +26 -0
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +62 -0
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +44 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +31 -0
- data/lib/rubocop/cop/correctors/punctuation_corrector.rb +29 -0
- data/lib/rubocop/cop/correctors/space_corrector.rb +34 -0
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +25 -0
- data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +31 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -0
- data/lib/rubocop/cop/generator.rb +18 -87
- data/lib/rubocop/cop/generator/require_file_injector.rb +78 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/align_array.rb +5 -1
- data/lib/rubocop/cop/layout/align_hash.rb +1 -1
- data/lib/rubocop/cop/layout/align_parameters.rb +5 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +2 -2
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +17 -19
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +4 -0
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +4 -0
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/indent_array.rb +6 -2
- data/lib/rubocop/cop/layout/indent_assignment.rb +6 -2
- data/lib/rubocop/cop/layout/indent_hash.rb +5 -1
- data/lib/rubocop/cop/layout/indentation_consistency.rb +5 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +5 -1
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -2
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/space_after_comma.rb +4 -0
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +4 -0
- data/lib/rubocop/cop/layout/space_before_comma.rb +4 -0
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +3 -2
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +16 -7
- data/lib/rubocop/cop/layout/tab.rb +1 -1
- data/lib/rubocop/cop/lint/block_alignment.rb +1 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -2
- data/lib/rubocop/cop/lint/end_alignment.rb +3 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +4 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +6 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -1
- data/lib/rubocop/cop/mixin/alignment.rb +70 -0
- data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/array_syntax.rb +2 -0
- data/lib/rubocop/cop/mixin/code_length.rb +2 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +2 -0
- data/lib/rubocop/cop/mixin/def_node.rb +3 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -15
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -25
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +0 -6
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +5 -9
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +2 -2
- data/lib/rubocop/cop/mixin/ignored_pattern.rb +2 -0
- data/lib/rubocop/cop/mixin/integer_node.rb +2 -0
- data/lib/rubocop/cop/mixin/match_range.rb +2 -0
- data/lib/rubocop/cop/mixin/min_body_length.rb +2 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -48
- data/lib/rubocop/cop/mixin/negative_conditional.rb +2 -16
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +12 -31
- data/lib/rubocop/cop/mixin/parentheses.rb +2 -19
- data/lib/rubocop/cop/mixin/percent_literal.rb +3 -3
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +2 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +2 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +2 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -2
- data/lib/rubocop/cop/mixin/string_help.rb +2 -0
- data/lib/rubocop/cop/mixin/string_literals_help.rb +2 -13
- data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -21
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -10
- data/lib/rubocop/cop/mixin/unused_argument.rb +2 -15
- data/lib/rubocop/cop/performance/case_when_splat.rb +1 -1
- data/lib/rubocop/cop/rails/action_filter.rb +3 -2
- data/lib/rubocop/cop/rails/active_support_aliases.rb +3 -2
- data/lib/rubocop/cop/rails/application_job.rb +6 -0
- data/lib/rubocop/cop/rails/application_record.rb +6 -0
- data/lib/rubocop/cop/rails/blank.rb +10 -9
- data/lib/rubocop/cop/rails/date.rb +22 -14
- data/lib/rubocop/cop/rails/delegate.rb +1 -1
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +3 -2
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +4 -2
- data/lib/rubocop/cop/rails/environment_comparison.rb +2 -2
- data/lib/rubocop/cop/rails/file_path.rb +1 -1
- data/lib/rubocop/cop/rails/find_by.rb +2 -2
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +15 -7
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
- data/lib/rubocop/cop/rails/inverse_of.rb +130 -8
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +3 -3
- data/lib/rubocop/cop/rails/pluralization_grammar.rb +3 -2
- data/lib/rubocop/cop/rails/presence.rb +31 -18
- data/lib/rubocop/cop/rails/present.rb +11 -8
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +52 -10
- data/lib/rubocop/cop/rails/request_referer.rb +2 -3
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +9 -2
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +38 -10
- data/lib/rubocop/cop/style/class_and_module_children.rb +76 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/format_string_token.rb +24 -4
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +46 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +4 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +14 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +79 -0
- data/lib/rubocop/cop/style/mixin_usage.rb +13 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +19 -0
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_while.rb +6 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +4 -0
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/string_literals.rb +4 -0
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -0
- data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +4 -0
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +33 -24
- data/lib/rubocop/options.rb +33 -10
- data/lib/rubocop/path_util.rb +7 -0
- data/lib/rubocop/token.rb +4 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +14 -4
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +0 -149
- data/lib/rubocop/cop/style/extend_self.rb +0 -92
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This class does condition auto-correction
|
6
|
+
class ConditionCorrector
|
7
|
+
class << self
|
8
|
+
def correct_negative_condition(node)
|
9
|
+
condition = negated_condition(node)
|
10
|
+
|
11
|
+
lambda do |corrector|
|
12
|
+
corrector.replace(node.loc.keyword, node.inverse_keyword)
|
13
|
+
corrector.replace(condition.source_range,
|
14
|
+
condition.children.first.source)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def negated_condition(node)
|
21
|
+
condition = node.condition
|
22
|
+
condition = condition.children.first while condition.begin_type?
|
23
|
+
condition
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This class does empty line auto-correction
|
6
|
+
class EmptyLineCorrector
|
7
|
+
class << self
|
8
|
+
def correct(node)
|
9
|
+
offense_style, range = node
|
10
|
+
lambda do |corrector|
|
11
|
+
case offense_style
|
12
|
+
when :no_empty_lines then
|
13
|
+
corrector.remove(range)
|
14
|
+
when :empty_lines then
|
15
|
+
corrector.insert_before(range, "\n")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def insert_before(node)
|
21
|
+
->(corrector) { corrector.insert_before(node.source_range, "\n") }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Autocorrection logic for the closing brace of a literal either
|
6
|
+
# on the same line as the last contained elements, or a new line.
|
7
|
+
class MultilineLiteralBraceCorrector
|
8
|
+
extend MultilineLiteralBraceLayout
|
9
|
+
extend Util
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :processed_source
|
13
|
+
|
14
|
+
# rubocop:disable Metrics/MethodLength
|
15
|
+
def correct(processed_source, node)
|
16
|
+
@processed_source = processed_source
|
17
|
+
if closing_brace_on_same_line?(node)
|
18
|
+
lambda do |corrector|
|
19
|
+
corrector.insert_before(node.loc.end, "\n".freeze)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
# When a comment immediately before the closing brace gets in the
|
23
|
+
# way of an easy correction, the offense is reported but not auto-
|
24
|
+
# corrected. The user must handle the delicate decision of where to
|
25
|
+
# put the comment.
|
26
|
+
return if new_line_needed_before_closing_brace?(node)
|
27
|
+
|
28
|
+
lambda do |corrector|
|
29
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.end,
|
30
|
+
side: :left))
|
31
|
+
|
32
|
+
corrector.insert_after(
|
33
|
+
last_element_range_with_trailing_comma(node),
|
34
|
+
node.loc.end.source
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
# rubocop:enable Metrics/MethodLength
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def last_element_range_with_trailing_comma(node)
|
44
|
+
trailing_comma_range = last_element_trailing_comma_range(node)
|
45
|
+
if trailing_comma_range
|
46
|
+
children(node).last.source_range.join(trailing_comma_range)
|
47
|
+
else
|
48
|
+
children(node).last.source_range
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def last_element_trailing_comma_range(node)
|
53
|
+
range = range_with_surrounding_space(
|
54
|
+
range: children(node).last.source_range,
|
55
|
+
side: :right
|
56
|
+
).end.resize(1)
|
57
|
+
range.source == ',' ? range : nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects gem dependency order
|
6
|
+
class OrderedGemCorrector
|
7
|
+
extend OrderedGemNode
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_reader :processed_source, :comments_as_separators
|
11
|
+
|
12
|
+
def correct(processed_source, node,
|
13
|
+
previous_declaration, comments_as_separators)
|
14
|
+
@processed_source = processed_source
|
15
|
+
@comments_as_separators = comments_as_separators
|
16
|
+
|
17
|
+
current_range = declaration_with_comment(node)
|
18
|
+
previous_range = declaration_with_comment(previous_declaration)
|
19
|
+
|
20
|
+
lambda do |corrector|
|
21
|
+
swap_range(corrector, current_range, previous_range)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def declaration_with_comment(node)
|
28
|
+
buffer = processed_source.buffer
|
29
|
+
begin_pos = get_source_range(node, comments_as_separators).begin_pos
|
30
|
+
end_line = buffer.line_for_position(node.loc.expression.end_pos)
|
31
|
+
end_pos = buffer.line_range(end_line).end_pos
|
32
|
+
Parser::Source::Range.new(buffer, begin_pos, end_pos)
|
33
|
+
end
|
34
|
+
|
35
|
+
def swap_range(corrector, range1, range2)
|
36
|
+
src1 = range1.source
|
37
|
+
src2 = range2.source
|
38
|
+
corrector.replace(range1, src2)
|
39
|
+
corrector.replace(range2, src1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects parentheses
|
6
|
+
class ParenthesesCorrector
|
7
|
+
class << self
|
8
|
+
def correct(node)
|
9
|
+
lambda do |corrector|
|
10
|
+
corrector.remove(node.loc.begin)
|
11
|
+
corrector.remove(node.loc.end)
|
12
|
+
|
13
|
+
if ternary_condition?(node) && next_char_is_question_mark?(node)
|
14
|
+
corrector.insert_after(node.loc.end, ' ')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def ternary_condition?(node)
|
22
|
+
node.parent && node.parent.if_type? && node.parent.ternary?
|
23
|
+
end
|
24
|
+
|
25
|
+
def next_char_is_question_mark?(node)
|
26
|
+
node.loc.last_column == node.parent.loc.question.column
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects punctuation
|
6
|
+
class PunctuationCorrector
|
7
|
+
class << self
|
8
|
+
def remove_space(space_before)
|
9
|
+
->(corrector) { corrector.remove(space_before) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_space(token)
|
13
|
+
->(corrector) { corrector.replace(token.pos, token.pos.source + ' ') }
|
14
|
+
end
|
15
|
+
|
16
|
+
def swap_comma(range)
|
17
|
+
return unless range
|
18
|
+
|
19
|
+
lambda do |corrector|
|
20
|
+
case range.source
|
21
|
+
when ',' then corrector.remove(range)
|
22
|
+
else corrector.insert_after(range, ',')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects whitespace
|
6
|
+
class SpaceCorrector
|
7
|
+
extend SurroundingSpace
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_reader :processed_source
|
11
|
+
|
12
|
+
def remove_space(processed_source, corrector, left_token, right_token)
|
13
|
+
@processed_source = processed_source
|
14
|
+
if left_token.space_after?
|
15
|
+
range = side_space_range(range: left_token.pos, side: :right)
|
16
|
+
corrector.remove(range)
|
17
|
+
end
|
18
|
+
return unless right_token.space_before?
|
19
|
+
range = side_space_range(range: right_token.pos, side: :left)
|
20
|
+
corrector.remove(range)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_space(processed_source, corrector, left_token, right_token)
|
24
|
+
@processed_source = processed_source
|
25
|
+
unless left_token.space_after?
|
26
|
+
corrector.insert_after(left_token.pos, ' ')
|
27
|
+
end
|
28
|
+
return if right_token.space_before?
|
29
|
+
corrector.insert_before(right_token.pos, ' ')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects string literals
|
6
|
+
class StringLiteralCorrector
|
7
|
+
extend Util
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def correct(node, style)
|
11
|
+
return if node.dstr_type?
|
12
|
+
|
13
|
+
lambda do |corrector|
|
14
|
+
str = node.str_content
|
15
|
+
if style == :single_quotes
|
16
|
+
corrector.replace(node.source_range, to_string_literal(str))
|
17
|
+
else
|
18
|
+
corrector.replace(node.source_range, str.inspect)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This auto-corrects unused arguments.
|
6
|
+
class UnusedArgCorrector
|
7
|
+
extend Util
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_reader :processed_source
|
11
|
+
|
12
|
+
def correct(processed_source, node)
|
13
|
+
return if %i[kwarg kwoptarg].include?(node.type)
|
14
|
+
|
15
|
+
@processed_source = processed_source
|
16
|
+
|
17
|
+
if node.blockarg_type?
|
18
|
+
lambda do |corrector|
|
19
|
+
range = range_with_surrounding_space(range: node.source_range,
|
20
|
+
side: :left)
|
21
|
+
range = range_with_surrounding_comma(range, :left)
|
22
|
+
corrector.remove(range)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
->(corrector) { corrector.insert_before(node.loc.name, '_') }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
60
60
|
register_offense(
|
61
61
|
node,
|
62
62
|
node.method_name,
|
63
|
-
nodes.first.
|
63
|
+
nodes.first.first_line
|
64
64
|
)
|
65
65
|
end
|
66
66
|
end
|
@@ -88,7 +88,7 @@ module RuboCop
|
|
88
88
|
def register_offense(node, assignment, line_of_first_occurrence)
|
89
89
|
line_range = node.loc.column...node.loc.last_column
|
90
90
|
offense_location =
|
91
|
-
source_range(processed_source.buffer, node.
|
91
|
+
source_range(processed_source.buffer, node.first_line, line_range)
|
92
92
|
message = format(
|
93
93
|
MSG,
|
94
94
|
assignment: assignment,
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
SPEC_TEMPLATE = <<-SPEC.strip_indent
|
55
55
|
# frozen_string_literal: true
|
56
56
|
|
57
|
-
describe RuboCop::Cop::%<department>s::%<cop_name>s do
|
57
|
+
RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s do
|
58
58
|
subject(:cop) { described_class.new(config) }
|
59
59
|
|
60
60
|
let(:config) { RuboCop::Config.new }
|
@@ -77,9 +77,9 @@ module RuboCop
|
|
77
77
|
end
|
78
78
|
SPEC
|
79
79
|
|
80
|
-
def initialize(name)
|
80
|
+
def initialize(name, output: $stdout)
|
81
81
|
@badge = Badge.parse(name)
|
82
|
-
|
82
|
+
@output = output
|
83
83
|
return if badge.qualified?
|
84
84
|
|
85
85
|
raise ArgumentError, 'Specify a cop name with Department/Name style'
|
@@ -93,12 +93,15 @@ module RuboCop
|
|
93
93
|
write_unless_file_exists(spec_path, generated_spec)
|
94
94
|
end
|
95
95
|
|
96
|
-
def inject_require
|
97
|
-
RequireFileInjector.new(
|
96
|
+
def inject_require(root_file_path: 'lib/rubocop.rb')
|
97
|
+
RequireFileInjector.new(
|
98
|
+
source_path: source_path,
|
99
|
+
root_file_path: root_file_path
|
100
|
+
).inject
|
98
101
|
end
|
99
102
|
|
100
|
-
def inject_config(
|
101
|
-
config = File.readlines(
|
103
|
+
def inject_config(config_file_path: 'config/enabled.yml')
|
104
|
+
config = File.readlines(config_file_path)
|
102
105
|
content = <<-YAML.strip_indent
|
103
106
|
#{badge}:
|
104
107
|
Description: 'TODO: Write a description of the cop.'
|
@@ -110,19 +113,15 @@ module RuboCop
|
|
110
113
|
break index - 1 if badge.to_s < line
|
111
114
|
end
|
112
115
|
config.insert(target_line, content)
|
113
|
-
File.write(
|
116
|
+
File.write(config_file_path, config.join)
|
117
|
+
output.puts <<-MESSAGE.strip_indent
|
118
|
+
[modify] A configuration for the cop is added into #{config_file_path}.
|
119
|
+
If you want to disable the cop by default, move the added config to config/disabled.yml
|
120
|
+
MESSAGE
|
114
121
|
end
|
115
122
|
|
116
123
|
def todo
|
117
124
|
<<-TODO.strip_indent
|
118
|
-
Files created:
|
119
|
-
- #{source_path}
|
120
|
-
- #{spec_path}
|
121
|
-
File modified:
|
122
|
-
- `require_relative '#{require_path}'` added into lib/rubocop.rb
|
123
|
-
- A configuration for the cop is added into config/enabled.yml
|
124
|
-
- If you want to disable the cop by default, move the added config to config/disabled.yml
|
125
|
-
|
126
125
|
Do 3 steps:
|
127
126
|
1. Add an entry to the "New features" section in CHANGELOG.md,
|
128
127
|
e.g. "Add new `#{badge}` cop. ([@your_id][])"
|
@@ -133,7 +132,7 @@ module RuboCop
|
|
133
132
|
|
134
133
|
private
|
135
134
|
|
136
|
-
attr_reader :badge
|
135
|
+
attr_reader :badge, :output
|
137
136
|
|
138
137
|
def write_unless_file_exists(path, contents)
|
139
138
|
if File.exist?(path)
|
@@ -145,6 +144,7 @@ module RuboCop
|
|
145
144
|
FileUtils.mkdir_p(dir) unless File.exist?(dir)
|
146
145
|
|
147
146
|
File.write(path, contents)
|
147
|
+
output.puts "[create] #{path}"
|
148
148
|
end
|
149
149
|
|
150
150
|
def generated_source
|
@@ -159,10 +159,6 @@ module RuboCop
|
|
159
159
|
format(template, department: badge.department, cop_name: badge.cop_name)
|
160
160
|
end
|
161
161
|
|
162
|
-
def require_path
|
163
|
-
source_path.sub('lib/', '').sub('.rb', '')
|
164
|
-
end
|
165
|
-
|
166
162
|
def spec_path
|
167
163
|
File.join(
|
168
164
|
'spec',
|
@@ -184,77 +180,12 @@ module RuboCop
|
|
184
180
|
end
|
185
181
|
|
186
182
|
def snake_case(camel_case_string)
|
183
|
+
return 'rspec' if camel_case_string == 'RSpec'
|
187
184
|
camel_case_string
|
188
185
|
.gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
|
189
186
|
.gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
|
190
187
|
.downcase
|
191
188
|
end
|
192
|
-
|
193
|
-
# A class that injects a require directive into the root RuboCop file.
|
194
|
-
# It looks for other directives that require files in the same (cop)
|
195
|
-
# namespace and injects the provided one in alpha
|
196
|
-
class RequireFileInjector
|
197
|
-
REQUIRE_PATH = /require_relative ['"](.+)['"]/
|
198
|
-
|
199
|
-
def initialize(require_path)
|
200
|
-
@require_path = require_path
|
201
|
-
@require_entries = File.readlines(rubocop_root_file_path)
|
202
|
-
end
|
203
|
-
|
204
|
-
def inject
|
205
|
-
return if require_exists? || !target_line
|
206
|
-
|
207
|
-
File.write(rubocop_root_file_path, updated_directives)
|
208
|
-
end
|
209
|
-
|
210
|
-
private
|
211
|
-
|
212
|
-
attr_reader :require_path, :require_entries
|
213
|
-
|
214
|
-
def rubocop_root_file_path
|
215
|
-
File.join('lib', 'rubocop.rb')
|
216
|
-
end
|
217
|
-
|
218
|
-
def require_exists?
|
219
|
-
require_entries.any? do |entry|
|
220
|
-
entry == injectable_require_directive
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
def updated_directives
|
225
|
-
require_entries.insert(target_line,
|
226
|
-
injectable_require_directive).join
|
227
|
-
end
|
228
|
-
|
229
|
-
def target_line
|
230
|
-
@target_line ||= begin
|
231
|
-
in_the_same_department = false
|
232
|
-
inject_parts = require_path_fragments(injectable_require_directive)
|
233
|
-
|
234
|
-
require_entries.find.with_index do |entry, index|
|
235
|
-
current_entry_parts = require_path_fragments(entry)
|
236
|
-
|
237
|
-
if inject_parts[0..-2] == current_entry_parts[0..-2]
|
238
|
-
in_the_same_department = true
|
239
|
-
|
240
|
-
break index if inject_parts.last < current_entry_parts.last
|
241
|
-
elsif in_the_same_department
|
242
|
-
break index
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def require_path_fragments(require_directove)
|
249
|
-
path = require_directove.match(REQUIRE_PATH)
|
250
|
-
|
251
|
-
path ? path.captures.first.split('/') : []
|
252
|
-
end
|
253
|
-
|
254
|
-
def injectable_require_directive
|
255
|
-
"require_relative '#{require_path}'\n"
|
256
|
-
end
|
257
|
-
end
|
258
189
|
end
|
259
190
|
end
|
260
191
|
end
|