rubocop 0.52.0 → 0.52.1
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.
- 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
|