rubocop 1.60.2 → 1.62.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 +1 -1
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +41 -12
- 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 +4 -0
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_validator.rb +14 -5
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +17 -8
- 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/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/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 +1 -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/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- 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/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -5
- data/lib/rubocop/cop/style/for.rb +2 -0
- 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/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 +2 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +4 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -6
- data/lib/rubocop/cop/style/redundant_return.rb +6 -0
- data/lib/rubocop/cop/style/sample.rb +1 -3
- 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/html_formatter.rb +30 -10
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- 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 +8 -8
- data/lib/rubocop/rspec/shared_contexts.rb +36 -17
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +9 -2
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +18 -3
- metadata +9 -6
@@ -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
|
|
@@ -22,10 +22,11 @@ module RuboCop
|
|
22
22
|
|
23
23
|
def on_send(node)
|
24
24
|
return unless node.method?(:require_relative)
|
25
|
-
return unless node.first_argument
|
26
|
-
return unless
|
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|
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
72
72
|
ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
|
73
73
|
ARGUMENT_TYPES = %i[
|
74
74
|
kFALSE kNIL kSELF kTRUE tCONSTANT tCVAR tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR
|
75
|
-
tLBRACK tLCURLY tLPAREN_ARG tSTRING tSTRING_BEG tSYMBOL tXSTRING_BEG
|
75
|
+
tLABEL tLBRACK tLCURLY tLPAREN_ARG tSTRING tSTRING_BEG tSYMBOL tXSTRING_BEG
|
76
76
|
].freeze
|
77
77
|
|
78
78
|
def on_new_investigation
|
@@ -124,8 +124,10 @@ module RuboCop
|
|
124
124
|
return true unless (node = find_node_for_line(range.line))
|
125
125
|
return false if argument_newline?(node)
|
126
126
|
|
127
|
-
|
128
|
-
|
127
|
+
continuation_node = node.parent || node
|
128
|
+
return false if allowed_type?(node) || allowed_type?(continuation_node)
|
129
|
+
|
130
|
+
continuation_node.source.include?("\n") || continuation_node.source.include?("\\\n")
|
129
131
|
end
|
130
132
|
|
131
133
|
def inside_string_literal?(range, token)
|
@@ -140,17 +142,22 @@ module RuboCop
|
|
140
142
|
current_token.type == :tIDENTIFIER && ARGUMENT_TYPES.include?(next_token.type)
|
141
143
|
end
|
142
144
|
|
145
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
143
146
|
def argument_newline?(node)
|
147
|
+
node = node.to_a.last if node.assignment?
|
148
|
+
return false if node.parenthesized_call?
|
149
|
+
|
144
150
|
node = node.children.first if node.root? && node.begin_type?
|
145
151
|
|
146
|
-
if argument_is_method?(node)
|
147
|
-
argument_newline?(node.
|
152
|
+
if argument_is_method?(node) || node.begin_type?
|
153
|
+
argument_newline?(node.children.first)
|
148
154
|
else
|
149
155
|
return false unless method_call_with_arguments?(node)
|
150
156
|
|
151
|
-
node
|
157
|
+
!same_line?(node, node.first_argument)
|
152
158
|
end
|
153
159
|
end
|
160
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
154
161
|
|
155
162
|
def find_node_for_line(line)
|
156
163
|
processed_source.ast.each_node do |node|
|
@@ -158,6 +165,10 @@ module RuboCop
|
|
158
165
|
end
|
159
166
|
end
|
160
167
|
|
168
|
+
def allowed_type?(node)
|
169
|
+
node.and_type? || node.or_type? || (node.if_type? && node.ternary?)
|
170
|
+
end
|
171
|
+
|
161
172
|
def same_line?(node, line)
|
162
173
|
return false unless (source_range = node.source_range)
|
163
174
|
|
@@ -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)
|
@@ -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
|
@@ -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
|
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
|
|
data/lib/rubocop/lsp/severity.rb
CHANGED
data/lib/rubocop/lsp.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# The RuboCop's built-in LSP module.
|
5
|
+
module LSP
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Returns true when LSP is enabled, false when disabled.
|
9
|
+
#
|
10
|
+
# @return [Boolean]
|
11
|
+
def enabled?
|
12
|
+
@enabled ||= false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Enable LSP.
|
16
|
+
#
|
17
|
+
# @return [void]
|
18
|
+
def enable
|
19
|
+
@enabled = true
|
20
|
+
end
|
21
|
+
|
22
|
+
# Disable LSP.
|
23
|
+
#
|
24
|
+
# @return [void]
|
25
|
+
def disable
|
26
|
+
@enabled = false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -268,7 +268,7 @@ module RuboCop
|
|
268
268
|
|
269
269
|
# Rewrite the comment without a given token type
|
270
270
|
def without(type)
|
271
|
-
if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/)
|
271
|
+
if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/io)
|
272
272
|
''
|
273
273
|
else
|
274
274
|
@comment
|
data/lib/rubocop/options.rb
CHANGED
@@ -95,6 +95,7 @@ module RuboCop
|
|
95
95
|
option(opts, '--ignore-unrecognized-cops')
|
96
96
|
option(opts, '--force-default-config')
|
97
97
|
option(opts, '-s', '--stdin FILE')
|
98
|
+
option(opts, '--editor-mode')
|
98
99
|
option(opts, '-P', '--[no-]parallel')
|
99
100
|
option(opts, '--raise-cop-error')
|
100
101
|
add_severity_option(opts)
|
@@ -369,6 +370,7 @@ module RuboCop
|
|
369
370
|
validate_display_only_failed
|
370
371
|
validate_display_only_failed_and_display_only_correctable
|
371
372
|
validate_display_only_correctable_and_autocorrect
|
373
|
+
validate_lsp_and_editor_mode
|
372
374
|
disable_parallel_when_invalid_option_combo
|
373
375
|
|
374
376
|
return if incompatible_options.size <= 1
|
@@ -416,6 +418,13 @@ module RuboCop
|
|
416
418
|
format('--display-only-failed cannot be used together with other display options.')
|
417
419
|
end
|
418
420
|
|
421
|
+
def validate_lsp_and_editor_mode
|
422
|
+
return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
|
423
|
+
|
424
|
+
raise OptionArgumentError,
|
425
|
+
format('Do not specify `--editor-mode` as it is redundant in `--lsp`.')
|
426
|
+
end
|
427
|
+
|
419
428
|
def validate_autocorrect
|
420
429
|
if @options.key?(:safe_autocorrect) && @options.key?(:autocorrect_all)
|
421
430
|
message = Rainbow(<<~MESSAGE).red
|
@@ -609,6 +618,8 @@ module RuboCop
|
|
609
618
|
'parallel. Default is true.'],
|
610
619
|
stdin: ['Pipe source from STDIN, using FILE in offense',
|
611
620
|
'reports. This is useful for editor integration.'],
|
621
|
+
editor_mode: ['Optimize real-time feedback in editors,',
|
622
|
+
'adjusting behaviors for editing experience.'],
|
612
623
|
init: 'Generate a .rubocop.yml file in the current directory.',
|
613
624
|
server: ['If a server process has not been started yet, start',
|
614
625
|
'the server process and execute inspection with server.',
|
data/lib/rubocop/path_util.rb
CHANGED
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
47
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
48
48
|
def match_path?(pattern, path)
|
49
49
|
case pattern
|
50
50
|
when String
|
@@ -52,6 +52,10 @@ module RuboCop
|
|
52
52
|
if pattern == path
|
53
53
|
true
|
54
54
|
elsif glob?(pattern)
|
55
|
+
# File name matching doesn't really work with relative patterns that start with "..". We
|
56
|
+
# get around that problem by converting the pattern to an absolute path.
|
57
|
+
pattern = File.expand_path(pattern) if pattern.start_with?('..')
|
58
|
+
|
55
59
|
File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
56
60
|
end
|
57
61
|
|
@@ -66,7 +70,7 @@ module RuboCop
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
end
|
69
|
-
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
73
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
70
74
|
|
71
75
|
# Returns true for an absolute Unix or Windows path.
|
72
76
|
def absolute?(path)
|
@@ -6,7 +6,11 @@ require 'tempfile'
|
|
6
6
|
module CopHelper
|
7
7
|
extend RSpec::SharedContext
|
8
8
|
|
9
|
-
let(:ruby_version)
|
9
|
+
let(:ruby_version) do
|
10
|
+
# The minimum version Prism can parse is 3.3.
|
11
|
+
ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
|
12
|
+
end
|
13
|
+
let(:parser_engine) { ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym }
|
10
14
|
let(:rails_version) { false }
|
11
15
|
|
12
16
|
def inspect_source(source, file = nil)
|
@@ -28,7 +32,9 @@ module CopHelper
|
|
28
32
|
file = file.path
|
29
33
|
end
|
30
34
|
|
31
|
-
processed_source = RuboCop::ProcessedSource.new(
|
35
|
+
processed_source = RuboCop::ProcessedSource.new(
|
36
|
+
source, ruby_version, file, parser_engine: parser_engine
|
37
|
+
)
|
32
38
|
processed_source.config = configuration
|
33
39
|
processed_source.registry = registry
|
34
40
|
processed_source
|
@@ -126,7 +126,7 @@ module RuboCop
|
|
126
126
|
@offenses
|
127
127
|
end
|
128
128
|
|
129
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
129
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
130
130
|
def expect_correction(correction, loop: true, source: nil)
|
131
131
|
if source
|
132
132
|
expected_annotations = parse_annotations(source, raise_error: false)
|
@@ -148,7 +148,6 @@ module RuboCop
|
|
148
148
|
|
149
149
|
break corrected_source unless loop
|
150
150
|
break corrected_source if @last_corrector.empty?
|
151
|
-
break corrected_source if corrected_source == @processed_source.buffer.source
|
152
151
|
|
153
152
|
if iteration > RuboCop::Runner::MAX_ITERATIONS
|
154
153
|
raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
|
@@ -163,19 +162,20 @@ module RuboCop
|
|
163
162
|
|
164
163
|
expect(new_source).to eq(correction)
|
165
164
|
end
|
166
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
165
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
167
166
|
|
168
167
|
def expect_no_corrections
|
169
168
|
raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
|
170
169
|
|
171
170
|
return if @last_corrector.empty?
|
172
171
|
|
173
|
-
#
|
174
|
-
# we need to run the actual corrections
|
175
|
-
|
172
|
+
# This is just here for a pretty diff if the source actually got changed
|
176
173
|
new_source = @last_corrector.rewrite
|
177
|
-
|
178
174
|
expect(new_source).to eq(@processed_source.buffer.source)
|
175
|
+
|
176
|
+
# There is an infinite loop if a corrector is present that did not make
|
177
|
+
# any changes. It will cause the same offense/correction on the next loop.
|
178
|
+
raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
|
179
179
|
end
|
180
180
|
|
181
181
|
def expect_no_offenses(source, file = nil)
|
@@ -212,7 +212,7 @@ module RuboCop
|
|
212
212
|
|
213
213
|
# Parsed representation of code annotated with the `^^^ Message` style
|
214
214
|
class AnnotatedSource
|
215
|
-
ANNOTATION_PATTERN = /\A\s*(\^+|\^{})
|
215
|
+
ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) ?/.freeze
|
216
216
|
ABBREV = "[...]\n"
|
217
217
|
|
218
218
|
# @param annotated_source [String] string passed to the matchers
|