rubocop 1.60.2 → 1.63.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +64 -15
- data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli.rb +6 -1
- data/lib/rubocop/config.rb +37 -10
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +14 -5
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +52 -6
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +11 -3
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -4
- data/lib/rubocop/cop/lint/debugger.rb +27 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
- data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/syntax.rb +1 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -2
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +6 -1
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +31 -12
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +29 -8
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +3 -3
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -5
- data/lib/rubocop/cop/style/copyright.rb +16 -11
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -0
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +10 -5
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +5 -8
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +4 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +5 -0
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +6 -0
- data/lib/rubocop/cop/style/sample.rb +1 -3
- data/lib/rubocop/cop/team.rb +3 -0
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +4 -2
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/html_formatter.rb +30 -10
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/lockfile.rb +34 -4
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +1 -1
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +5 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +29 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +11 -0
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +49 -18
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +12 -2
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +1 -0
- metadata +10 -6
@@ -38,6 +38,7 @@ module RuboCop
|
|
38
38
|
|
39
39
|
private
|
40
40
|
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
41
42
|
def autocorrect(corrector, node, begin_of_arguments)
|
42
43
|
arguments = node.arguments
|
43
44
|
joined_arguments = arguments.map(&:source).join(', ')
|
@@ -49,9 +50,17 @@ module RuboCop
|
|
49
50
|
corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
|
50
51
|
end
|
51
52
|
|
52
|
-
|
53
|
+
arguments_range = arguments_range(node)
|
54
|
+
# If the method name isn't on the same line as def, move it directly after def
|
55
|
+
if arguments_range.first_line != opening_line(node)
|
56
|
+
corrector.remove(node.loc.name)
|
57
|
+
corrector.insert_after(node.loc.keyword, " #{node.loc.name.source}")
|
58
|
+
end
|
59
|
+
|
60
|
+
corrector.remove(arguments_range)
|
53
61
|
corrector.insert_after(begin_of_arguments, joined_arguments)
|
54
62
|
end
|
63
|
+
# rubocop:enable Metrics/AbcSize
|
55
64
|
|
56
65
|
def last_line_source_of_arguments(arguments)
|
57
66
|
processed_source[arguments.last_line - 1].strip
|
@@ -47,7 +47,11 @@ module RuboCop
|
|
47
47
|
message = enforce_single_line_ternary_operator?(node) ? MSG_SINGLE_LINE : MSG_IF
|
48
48
|
|
49
49
|
add_offense(node, message: message) do |corrector|
|
50
|
+
next if part_of_ignored_node?(node)
|
51
|
+
|
50
52
|
autocorrect(corrector, node)
|
53
|
+
|
54
|
+
ignore_node(node)
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
@@ -46,15 +46,17 @@ module RuboCop
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def check_method_node(node)
|
49
|
-
return unless preferred_method(node)
|
49
|
+
return unless preferred_method?(node)
|
50
50
|
|
51
51
|
message = message(node)
|
52
52
|
add_offense(node.loc.selector, message: message) do |corrector|
|
53
|
-
|
53
|
+
prefer = style == :then && node.receiver.nil? ? 'self.then' : style
|
54
|
+
|
55
|
+
corrector.replace(node.loc.selector, prefer)
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
57
|
-
def preferred_method(node)
|
59
|
+
def preferred_method?(node)
|
58
60
|
case style
|
59
61
|
when :then
|
60
62
|
node.method?(:yield_self)
|
@@ -289,9 +289,7 @@ module RuboCop
|
|
289
289
|
private
|
290
290
|
|
291
291
|
def modifier_range(node)
|
292
|
-
|
293
|
-
node.loc.keyword.begin_pos,
|
294
|
-
node.source_range.end_pos)
|
292
|
+
node.loc.keyword.join(node.source_range.end)
|
295
293
|
end
|
296
294
|
end
|
297
295
|
end
|
@@ -16,6 +16,9 @@ module RuboCop
|
|
16
16
|
# The exploded style has an `AllowedCompactTypes` configuration
|
17
17
|
# option that takes an Array of exception name Strings.
|
18
18
|
#
|
19
|
+
# @safety
|
20
|
+
# This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
|
21
|
+
#
|
19
22
|
# @example EnforcedStyle: exploded (default)
|
20
23
|
# # bad
|
21
24
|
# raise StandardError.new('message')
|
@@ -77,7 +80,7 @@ module RuboCop
|
|
77
80
|
|
78
81
|
def correction_exploded_to_compact(node)
|
79
82
|
exception_node, *message_nodes = *node.arguments
|
80
|
-
return
|
83
|
+
return if message_nodes.size > 1
|
81
84
|
|
82
85
|
argument = message_nodes.first.source
|
83
86
|
exception_class = exception_node.receiver&.source || exception_node.source
|
@@ -81,14 +81,20 @@ module RuboCop
|
|
81
81
|
redundant_argument = redundant_arg_for_method(node.method_name.to_s)
|
82
82
|
return false if redundant_argument.nil?
|
83
83
|
|
84
|
-
node.first_argument
|
84
|
+
target_argument = if node.first_argument.respond_to?(:value)
|
85
|
+
node.first_argument.value
|
86
|
+
else
|
87
|
+
node.first_argument
|
88
|
+
end
|
89
|
+
|
90
|
+
argument_matched?(target_argument, redundant_argument)
|
85
91
|
end
|
86
92
|
|
87
93
|
def redundant_arg_for_method(method_name)
|
88
94
|
arg = cop_config['Methods'].fetch(method_name) { return }
|
89
95
|
|
90
96
|
@mem ||= {}
|
91
|
-
@mem[method_name] ||=
|
97
|
+
@mem[method_name] ||= arg.inspect
|
92
98
|
end
|
93
99
|
|
94
100
|
def argument_range(node)
|
@@ -98,6 +104,23 @@ module RuboCop
|
|
98
104
|
range_with_surrounding_space(node.first_argument.source_range, newlines: false)
|
99
105
|
end
|
100
106
|
end
|
107
|
+
|
108
|
+
def argument_matched?(target_argument, redundant_argument)
|
109
|
+
argument = if target_argument.is_a?(AST::Node)
|
110
|
+
target_argument.source
|
111
|
+
elsif exclude_cntrl_character?(target_argument, redundant_argument)
|
112
|
+
target_argument.inspect
|
113
|
+
else
|
114
|
+
target_argument.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
argument == redundant_argument
|
118
|
+
end
|
119
|
+
|
120
|
+
def exclude_cntrl_character?(target_argument, redundant_argument)
|
121
|
+
!target_argument.to_s.sub(/\A'/, '"').sub(/'\z/, '"').match?(/[[:cntrl:]]/) ||
|
122
|
+
!redundant_argument.match?(/[[:cntrl:]]/)
|
123
|
+
end
|
101
124
|
end
|
102
125
|
end
|
103
126
|
end
|
@@ -54,12 +54,14 @@ module RuboCop
|
|
54
54
|
|
55
55
|
private
|
56
56
|
|
57
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
57
58
|
def check_branch(node)
|
58
59
|
return unless node
|
59
60
|
|
60
61
|
case node.type
|
61
|
-
when :case
|
62
|
-
when :
|
62
|
+
when :case then check_case_node(node)
|
63
|
+
when :case_match then check_case_match_node(node)
|
64
|
+
when :if then check_if_node(node)
|
63
65
|
when :rescue, :resbody
|
64
66
|
check_rescue_node(node)
|
65
67
|
when :ensure then check_ensure_node(node)
|
@@ -67,12 +69,18 @@ module RuboCop
|
|
67
69
|
check_begin_node(node)
|
68
70
|
end
|
69
71
|
end
|
72
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
70
73
|
|
71
74
|
def check_case_node(node)
|
72
75
|
node.when_branches.each { |when_node| check_branch(when_node.body) }
|
73
76
|
check_branch(node.else_branch)
|
74
77
|
end
|
75
78
|
|
79
|
+
def check_case_match_node(node)
|
80
|
+
node.in_pattern_branches.each { |in_pattern_node| check_branch(in_pattern_node.body) }
|
81
|
+
check_branch(node.else_branch)
|
82
|
+
end
|
83
|
+
|
76
84
|
def check_if_node(node)
|
77
85
|
return if node.modifier_form? || node.ternary?
|
78
86
|
|
@@ -18,14 +18,15 @@ module RuboCop
|
|
18
18
|
extend AutoCorrector
|
19
19
|
|
20
20
|
MSG = 'Remove the redundant current directory path.'
|
21
|
+
RESTRICT_ON_SEND = %i[require_relative].freeze
|
21
22
|
CURRENT_DIRECTORY_PATH = './'
|
22
23
|
|
23
24
|
def on_send(node)
|
24
|
-
return unless node.
|
25
|
-
return unless
|
26
|
-
return unless (index =
|
25
|
+
return unless (first_argument = node.first_argument)
|
26
|
+
return unless first_argument.str_content&.start_with?(CURRENT_DIRECTORY_PATH)
|
27
|
+
return unless (index = first_argument.source.index(CURRENT_DIRECTORY_PATH))
|
27
28
|
|
28
|
-
begin_pos =
|
29
|
+
begin_pos = first_argument.source_range.begin.begin_pos + index
|
29
30
|
range = range_between(begin_pos, begin_pos + 2)
|
30
31
|
|
31
32
|
add_offense(range) do |corrector|
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
private_constant :REPLACEMENT_METHODS
|
80
80
|
|
81
81
|
def on_send(node)
|
82
|
-
return if node.arguments? || node.
|
82
|
+
return if node.arguments? || node.block_literal?
|
83
83
|
|
84
84
|
select_predicate?(node) do |select_node, filter_method|
|
85
85
|
return if RAILS_METHODS.include?(filter_method) && !active_support_extensions_enabled?
|
@@ -140,7 +140,11 @@ module RuboCop
|
|
140
140
|
current_token.type == :tIDENTIFIER && ARGUMENT_TYPES.include?(next_token.type)
|
141
141
|
end
|
142
142
|
|
143
|
+
# rubocop:disable Metrics/AbcSize
|
143
144
|
def argument_newline?(node)
|
145
|
+
node = node.to_a.last if node.assignment?
|
146
|
+
return false if node.parenthesized_call?
|
147
|
+
|
144
148
|
node = node.children.first if node.root? && node.begin_type?
|
145
149
|
|
146
150
|
if argument_is_method?(node)
|
@@ -151,6 +155,7 @@ module RuboCop
|
|
151
155
|
node.loc.selector.line != node.first_argument.loc.line
|
152
156
|
end
|
153
157
|
end
|
158
|
+
# rubocop:enable Metrics/AbcSize
|
154
159
|
|
155
160
|
def find_node_for_line(line)
|
156
161
|
processed_source.ast.each_node do |node|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
return if interpolated_quotes?(node) || allowed_percent_q?(node)
|
54
54
|
|
55
55
|
add_offense(node) do |corrector|
|
56
|
-
delimiter =
|
56
|
+
delimiter = /\A%Q[^"]+\z|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
|
57
57
|
|
58
58
|
corrector.replace(node.loc.begin, delimiter)
|
59
59
|
corrector.replace(node.loc.end, delimiter)
|
@@ -113,6 +113,7 @@ module RuboCop
|
|
113
113
|
case node.type
|
114
114
|
when :return then check_return_node(node)
|
115
115
|
when :case then check_case_node(node)
|
116
|
+
when :case_match then check_case_match_node(node)
|
116
117
|
when :if then check_if_node(node)
|
117
118
|
when :rescue then check_rescue_node(node)
|
118
119
|
when :resbody then check_resbody_node(node)
|
@@ -140,6 +141,11 @@ module RuboCop
|
|
140
141
|
check_branch(node.else_branch)
|
141
142
|
end
|
142
143
|
|
144
|
+
def check_case_match_node(node)
|
145
|
+
node.in_pattern_branches.each { |in_pattern_node| check_branch(in_pattern_node.body) }
|
146
|
+
check_branch(node.else_branch)
|
147
|
+
end
|
148
|
+
|
143
149
|
def check_if_node(node)
|
144
150
|
return if node.ternary?
|
145
151
|
|
@@ -110,9 +110,7 @@ module RuboCop
|
|
110
110
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
111
111
|
|
112
112
|
def source_range(shuffle_node, node)
|
113
|
-
|
114
|
-
shuffle_node.loc.selector.begin_pos,
|
115
|
-
node.source_range.end_pos)
|
113
|
+
shuffle_node.loc.selector.join(node.source_range.end)
|
116
114
|
end
|
117
115
|
|
118
116
|
def message(shuffle_arg, method, method_args, range)
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -174,6 +174,9 @@ module RuboCop
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def support_target_rails_version?(cop)
|
177
|
+
# In this case, the rails version was already checked by `#excluded_file?`
|
178
|
+
return true if defined?(RuboCop::Rails::TargetRailsVersion::USES_REQUIRES_GEM_API)
|
179
|
+
|
177
180
|
return true unless cop.class.respond_to?(:support_target_rails_version?)
|
178
181
|
|
179
182
|
cop.class.support_target_rails_version?(cop.target_rails_version)
|
@@ -97,7 +97,9 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
97
97
|
'Version Changed'
|
98
98
|
]
|
99
99
|
autocorrect = if cop.support_autocorrect?
|
100
|
-
|
100
|
+
context = cop.new.always_autocorrect? ? 'Always' : 'Command-line only'
|
101
|
+
|
102
|
+
"#{context}#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}"
|
101
103
|
else
|
102
104
|
'No'
|
103
105
|
end
|
@@ -276,7 +278,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
276
278
|
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
277
279
|
cop_config = config.for_cop(cop)
|
278
280
|
non_display_keys = %w[
|
279
|
-
Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
281
|
+
AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
280
282
|
VersionChanged
|
281
283
|
]
|
282
284
|
pars = cop_config.reject { |k| non_display_keys.include? k }
|
@@ -6,9 +6,11 @@ module RuboCop
|
|
6
6
|
# cops it contains.
|
7
7
|
class DirectiveComment
|
8
8
|
# @api private
|
9
|
-
|
9
|
+
LINT_DEPARTMENT = 'Lint'
|
10
10
|
# @api private
|
11
|
-
|
11
|
+
LINT_REDUNDANT_DIRECTIVE_COP = "#{LINT_DEPARTMENT}/RedundantCopDisableDirective"
|
12
|
+
# @api private
|
13
|
+
LINT_SYNTAX_COP = "#{LINT_DEPARTMENT}/Syntax"
|
12
14
|
# @api private
|
13
15
|
COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
|
14
16
|
# @api private
|
@@ -118,9 +120,10 @@ module RuboCop
|
|
118
120
|
end
|
119
121
|
|
120
122
|
def parsed_cop_names
|
121
|
-
splitted_cops_string.map do |name|
|
123
|
+
cops = splitted_cops_string.map do |name|
|
122
124
|
department?(name) ? cop_names_for_department(name) : name
|
123
125
|
end.flatten
|
126
|
+
cops - [LINT_SYNTAX_COP]
|
124
127
|
end
|
125
128
|
|
126
129
|
def department?(name)
|
@@ -128,17 +131,16 @@ module RuboCop
|
|
128
131
|
end
|
129
132
|
|
130
133
|
def all_cop_names
|
131
|
-
|
134
|
+
exclude_lint_department_cops(cop_registry.names)
|
132
135
|
end
|
133
136
|
|
134
137
|
def cop_names_for_department(department)
|
135
138
|
names = cop_registry.names_for_department(department)
|
136
|
-
|
137
|
-
has_redundant_directive_cop ? exclude_redundant_directive_cop(names) : names
|
139
|
+
department == LINT_DEPARTMENT ? exclude_lint_department_cops(names) : names
|
138
140
|
end
|
139
141
|
|
140
|
-
def
|
141
|
-
cops - [
|
142
|
+
def exclude_lint_department_cops(cops)
|
143
|
+
cops - [LINT_REDUNDANT_DIRECTIVE_COP, LINT_SYNTAX_COP]
|
142
144
|
end
|
143
145
|
end
|
144
146
|
end
|
@@ -24,14 +24,10 @@ module RuboCop
|
|
24
24
|
message: message(offense)
|
25
25
|
)
|
26
26
|
|
27
|
-
|
28
|
-
return unless valid_line?(offense)
|
27
|
+
return unless valid_line?(offense)
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
rescue IndexError
|
33
|
-
# range is not on a valid line; perhaps the source file is empty
|
34
|
-
end
|
29
|
+
report_line(offense.location)
|
30
|
+
report_highlighted_area(offense.highlighted_area)
|
35
31
|
end
|
36
32
|
|
37
33
|
def valid_line?(offense)
|
@@ -9,6 +9,7 @@ module RuboCop
|
|
9
9
|
class HTMLFormatter < BaseFormatter
|
10
10
|
ELLIPSES = '<span class="extra-code">...</span>'
|
11
11
|
TEMPLATE_PATH = File.expand_path('../../../assets/output.html.erb', __dir__)
|
12
|
+
CSS_PATH = File.expand_path('../../../assets/output.css.erb', __dir__)
|
12
13
|
|
13
14
|
Color = Struct.new(:red, :green, :blue, :alpha) do
|
14
15
|
def to_s
|
@@ -50,8 +51,8 @@ module RuboCop
|
|
50
51
|
context = ERBContext.new(files, summary)
|
51
52
|
|
52
53
|
template = File.read(TEMPLATE_PATH, encoding: Encoding::UTF_8)
|
53
|
-
erb = ERB.new(template
|
54
|
-
html = erb.result(context.binding)
|
54
|
+
erb = ERB.new(template)
|
55
|
+
html = erb.result(context.binding).lines.map { (_1 =~ /^\s*$/).nil? ? _1 : "\n" }.join
|
55
56
|
|
56
57
|
output.write html
|
57
58
|
end
|
@@ -61,14 +62,6 @@ module RuboCop
|
|
61
62
|
include PathUtil
|
62
63
|
include TextUtil
|
63
64
|
|
64
|
-
SEVERITY_COLORS = {
|
65
|
-
refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
|
66
|
-
convention: Color.new(0xED, 0x9C, 0x28, 1.0),
|
67
|
-
warning: Color.new(0x96, 0x28, 0xEF, 1.0),
|
68
|
-
error: Color.new(0xD2, 0x32, 0x2D, 1.0),
|
69
|
-
fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
|
70
|
-
}.freeze
|
71
|
-
|
72
65
|
LOGO_IMAGE_PATH = File.expand_path('../../../assets/logo.png', __dir__)
|
73
66
|
|
74
67
|
attr_reader :files, :summary
|
@@ -127,6 +120,33 @@ module RuboCop
|
|
127
120
|
# https://github.com/ruby/base64/blob/v0.1.1/lib/base64.rb#L27-L40
|
128
121
|
[image].pack('m')
|
129
122
|
end
|
123
|
+
|
124
|
+
def render_css
|
125
|
+
context = CSSContext.new
|
126
|
+
template = File.read(CSS_PATH, encoding: Encoding::UTF_8)
|
127
|
+
erb = ERB.new(template, trim_mode: '-')
|
128
|
+
erb.result(context.binding).lines.map do |line|
|
129
|
+
line == "\n" ? line : " #{line}"
|
130
|
+
end.join
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# This class provides helper methods used in the ERB CSS template.
|
135
|
+
class CSSContext
|
136
|
+
SEVERITY_COLORS = {
|
137
|
+
refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
|
138
|
+
convention: Color.new(0xED, 0x9C, 0x28, 1.0),
|
139
|
+
warning: Color.new(0x96, 0x28, 0xEF, 1.0),
|
140
|
+
error: Color.new(0xD2, 0x32, 0x2D, 1.0),
|
141
|
+
fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
|
142
|
+
}.freeze
|
143
|
+
|
144
|
+
# Make Kernel#binding public.
|
145
|
+
# rubocop:disable Lint/UselessMethodDefinition
|
146
|
+
def binding
|
147
|
+
super
|
148
|
+
end
|
149
|
+
# rubocop:enable Lint/UselessMethodDefinition
|
130
150
|
end
|
131
151
|
end
|
132
152
|
end
|
@@ -61,8 +61,7 @@ module RuboCop
|
|
61
61
|
|
62
62
|
column_width = total_count.to_s.length + 2
|
63
63
|
per_cop_counts.each do |cop_name, count|
|
64
|
-
output.puts "#{count.to_s.ljust(column_width)}#{cop_name}"
|
65
|
-
"#{@style_guide_links[cop_name]}\n"
|
64
|
+
output.puts "#{count.to_s.ljust(column_width)}#{cop_information(cop_name)}"
|
66
65
|
end
|
67
66
|
output.puts '--'
|
68
67
|
output.puts "#{total_count} Total in #{offending_files_count} files"
|
@@ -78,6 +77,17 @@ module RuboCop
|
|
78
77
|
def total_offense_count(offense_counts)
|
79
78
|
offense_counts.values.sum
|
80
79
|
end
|
80
|
+
|
81
|
+
def cop_information(cop_name)
|
82
|
+
cop = RuboCop::Cop::Registry.global.find_by_cop_name(cop_name).new
|
83
|
+
|
84
|
+
if cop.correctable?
|
85
|
+
safety = cop.safe_autocorrect? ? 'Safe' : 'Unsafe'
|
86
|
+
correctable = Rainbow(" [#{safety} Correctable]").yellow
|
87
|
+
end
|
88
|
+
|
89
|
+
"#{cop_name}#{correctable}#{@style_guide_links[cop_name]}"
|
90
|
+
end
|
81
91
|
end
|
82
92
|
end
|
83
93
|
end
|
@@ -53,14 +53,10 @@ module RuboCop
|
|
53
53
|
message: message(offense)
|
54
54
|
)
|
55
55
|
|
56
|
-
|
57
|
-
return unless valid_line?(offense)
|
56
|
+
return unless valid_line?(offense)
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
rescue IndexError
|
62
|
-
# range is not on a valid line; perhaps the source file is empty
|
63
|
-
end
|
58
|
+
report_line(offense.location)
|
59
|
+
report_highlighted_area(offense.highlighted_area)
|
64
60
|
end
|
65
61
|
|
66
62
|
def annotate_message(msg)
|
data/lib/rubocop/lockfile.rb
CHANGED
@@ -5,14 +5,23 @@ module RuboCop
|
|
5
5
|
# Does not actually resolve gems, just parses the lockfile.
|
6
6
|
# @api private
|
7
7
|
class Lockfile
|
8
|
-
#
|
8
|
+
# @param [String, Pathname, nil] lockfile_path
|
9
|
+
def initialize(lockfile_path = nil)
|
10
|
+
lockfile_path ||= defined?(Bundler) ? Bundler.default_lockfile : nil
|
11
|
+
|
12
|
+
@lockfile_path = lockfile_path
|
13
|
+
end
|
14
|
+
|
15
|
+
# Gems that the bundle directly depends on.
|
16
|
+
# @return [Array<Bundler::Dependency>, nil]
|
9
17
|
def dependencies
|
10
18
|
return [] unless parser
|
11
19
|
|
12
20
|
parser.dependencies.values
|
13
21
|
end
|
14
22
|
|
15
|
-
# All activated gems, including transitive dependencies
|
23
|
+
# All activated gems, including transitive dependencies.
|
24
|
+
# @return [Array<Bundler::Dependency>, nil]
|
16
25
|
def gems
|
17
26
|
return [] unless parser
|
18
27
|
|
@@ -21,17 +30,38 @@ module RuboCop
|
|
21
30
|
parser.dependencies.values.concat(parser.specs.flat_map(&:dependencies))
|
22
31
|
end
|
23
32
|
|
33
|
+
# Returns the locked versions of gems from this lockfile.
|
34
|
+
# @param [Boolean] include_transitive_dependencies: When false, only direct dependencies
|
35
|
+
# are returned, i.e. those listed explicitly in the `Gemfile`.
|
36
|
+
# @returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems' names.
|
37
|
+
def gem_versions(include_transitive_dependencies: true)
|
38
|
+
return {} unless parser
|
39
|
+
|
40
|
+
all_gem_versions = parser.specs.to_h { |spec| [spec.name, spec.version] }
|
41
|
+
|
42
|
+
if include_transitive_dependencies
|
43
|
+
all_gem_versions
|
44
|
+
else
|
45
|
+
direct_dep_names = parser.dependencies.keys
|
46
|
+
all_gem_versions.slice(*direct_dep_names)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Whether this lockfile includes the named gem, directly or indirectly.
|
51
|
+
# @param [String] name
|
52
|
+
# @return [Boolean]
|
24
53
|
def includes_gem?(name)
|
25
54
|
gems.any? { |gem| gem.name == name }
|
26
55
|
end
|
27
56
|
|
28
57
|
private
|
29
58
|
|
59
|
+
# @return [Bundler::LockfileParser, nil]
|
30
60
|
def parser
|
31
|
-
return unless defined?(Bundler) && Bundler.default_lockfile
|
32
61
|
return @parser if defined?(@parser)
|
62
|
+
return unless @lockfile_path
|
33
63
|
|
34
|
-
lockfile = Bundler.read_file(
|
64
|
+
lockfile = Bundler.read_file(@lockfile_path)
|
35
65
|
@parser = lockfile ? Bundler::LockfileParser.new(lockfile) : nil
|
36
66
|
rescue Bundler::BundlerError
|
37
67
|
nil
|
data/lib/rubocop/lsp/logger.rb
CHANGED
data/lib/rubocop/lsp/routes.rb
CHANGED
data/lib/rubocop/lsp/runtime.rb
CHANGED
data/lib/rubocop/lsp/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'language_server-protocol'
|
4
|
+
require_relative '../lsp'
|
4
5
|
require_relative 'logger'
|
5
6
|
require_relative 'routes'
|
6
7
|
require_relative 'runtime'
|
@@ -15,14 +16,16 @@ require_relative 'runtime'
|
|
15
16
|
# https://github.com/standardrb/standard/blob/main/LICENSE.txt
|
16
17
|
#
|
17
18
|
module RuboCop
|
18
|
-
module
|
19
|
+
module LSP
|
19
20
|
# Language Server Protocol of RuboCop.
|
20
21
|
# @api private
|
21
22
|
class Server
|
22
23
|
def initialize(config_store)
|
24
|
+
RuboCop::LSP.enable
|
25
|
+
|
23
26
|
@reader = LanguageServer::Protocol::Transport::Io::Reader.new($stdin)
|
24
27
|
@writer = LanguageServer::Protocol::Transport::Io::Writer.new($stdout)
|
25
|
-
@runtime = RuboCop::
|
28
|
+
@runtime = RuboCop::LSP::Runtime.new(config_store)
|
26
29
|
@routes = Routes.new(self)
|
27
30
|
end
|
28
31
|
|