rubocop 0.46.0 → 0.47.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +77 -2
- data/config/default.yml +151 -74
- data/config/disabled.yml +9 -0
- data/config/enabled.yml +49 -9
- data/lib/rubocop.rb +36 -8
- data/lib/rubocop/ast/builder.rb +59 -0
- data/lib/rubocop/ast/node.rb +607 -0
- data/lib/rubocop/ast/node/array_node.rb +45 -0
- data/lib/rubocop/ast/node/case_node.rb +63 -0
- data/lib/rubocop/ast/node/for_node.rb +53 -0
- data/lib/rubocop/ast/node/hash_node.rb +102 -0
- data/lib/rubocop/ast/node/if_node.rb +136 -0
- data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
- data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
- data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
- data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
- data/lib/rubocop/ast/node/pair_node.rb +64 -0
- data/lib/rubocop/ast/node/until_node.rb +43 -0
- data/lib/rubocop/ast/node/when_node.rb +61 -0
- data/lib/rubocop/ast/node/while_node.rb +43 -0
- data/lib/rubocop/ast/sexp.rb +16 -0
- data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
- data/lib/rubocop/cli.rb +18 -14
- data/lib/rubocop/comment_config.rb +1 -3
- data/lib/rubocop/config.rb +93 -35
- data/lib/rubocop/config_loader.rb +1 -1
- data/lib/rubocop/cop/badge.rb +73 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
- data/lib/rubocop/cop/commissioner.rb +17 -6
- data/lib/rubocop/cop/cop.rb +25 -112
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
- data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
- data/lib/rubocop/cop/lint/condition_position.rb +14 -16
- data/lib/rubocop/cop/lint/debugger.rb +28 -0
- data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
- data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
- data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
- data/lib/rubocop/cop/lint/else_layout.rb +26 -29
- data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
- data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/empty_when.rb +14 -16
- data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
- data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
- data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
- data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
- data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
- data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
- data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/loop.rb +36 -0
- data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
- data/lib/rubocop/cop/lint/rand_one.rb +7 -3
- data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
- data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
- data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
- data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
- data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
- data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
- data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
- data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
- data/lib/rubocop/cop/lint/void.rb +52 -0
- data/lib/rubocop/cop/message_annotator.rb +102 -0
- data/lib/rubocop/cop/metrics/block_length.rb +6 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
- data/lib/rubocop/cop/metrics/line_length.rb +11 -4
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
- data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
- data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
- data/lib/rubocop/cop/mixin/duplication.rb +46 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
- data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
- data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
- data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
- data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
- data/lib/rubocop/cop/offense.rb +1 -1
- data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
- data/lib/rubocop/cop/performance/detect.rb +2 -2
- data/lib/rubocop/cop/performance/flat_map.rb +3 -3
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
- data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
- data/lib/rubocop/cop/rails/file_path.rb +80 -0
- data/lib/rubocop/cop/rails/find_each.rb +5 -14
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
- data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
- data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
- data/lib/rubocop/cop/rails/time_zone.rb +1 -1
- data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
- data/lib/rubocop/cop/registry.rb +170 -0
- data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
- data/lib/rubocop/cop/security/marshal_load.rb +33 -0
- data/lib/rubocop/cop/security/yaml_load.rb +37 -0
- data/lib/rubocop/cop/style/align_hash.rb +138 -169
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
- data/lib/rubocop/cop/style/case_indentation.rb +36 -27
- data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
- data/lib/rubocop/cop/style/each_with_object.rb +4 -1
- data/lib/rubocop/cop/style/else_alignment.rb +14 -20
- data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
- data/lib/rubocop/cop/style/empty_else.rb +20 -22
- data/lib/rubocop/cop/style/empty_literal.rb +4 -4
- data/lib/rubocop/cop/style/empty_method.rb +12 -6
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/file_name.rb +24 -4
- data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +17 -48
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
- data/lib/rubocop/cop/style/guard_clause.rb +11 -17
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
- data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
- data/lib/rubocop/cop/style/indent_array.rb +1 -1
- data/lib/rubocop/cop/style/indentation_width.rb +29 -60
- data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
- data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
- data/lib/rubocop/cop/style/missing_else.rb +40 -14
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
- data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
- data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
- data/lib/rubocop/cop/style/negated_if.rb +3 -19
- data/lib/rubocop/cop/style/negated_while.rb +2 -17
- data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
- data/lib/rubocop/cop/style/next.rb +23 -21
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
- data/lib/rubocop/cop/style/not.rb +1 -3
- data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
- data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
- data/lib/rubocop/cop/style/option_hash.rb +4 -15
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
- data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
- data/lib/rubocop/cop/style/redundant_return.rb +4 -8
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
- data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
- data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
- data/lib/rubocop/cop/style/string_methods.rb +1 -3
- data/lib/rubocop/cop/style/symbol_array.rb +1 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
- data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +1 -5
- data/lib/rubocop/cop/style/when_then.rb +4 -2
- data/lib/rubocop/cop/style/while_until_do.rb +9 -13
- data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
- data/lib/rubocop/cop/style/word_array.rb +5 -9
- data/lib/rubocop/cop/team.rb +16 -15
- data/lib/rubocop/cop/util.rb +13 -3
- data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/magic_comment.rb +196 -0
- data/lib/rubocop/options.rb +5 -4
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/shared_examples.rb +1 -1
- data/lib/rubocop/runner.rb +7 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +41 -14
- data/lib/rubocop/ast_node.rb +0 -624
- data/lib/rubocop/ast_node/builder.rb +0 -30
- data/lib/rubocop/ast_node/sexp.rb +0 -13
- data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
- data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -9,6 +9,8 @@ module RuboCop
|
|
9
9
|
class WhileUntilModifier < Cop
|
10
10
|
include StatementModifier
|
11
11
|
|
12
|
+
MSG = 'Favor modifier `%s` usage when having a single-line body.'.freeze
|
13
|
+
|
12
14
|
def on_while(node)
|
13
15
|
check(node)
|
14
16
|
end
|
@@ -17,22 +19,21 @@ module RuboCop
|
|
17
19
|
check(node)
|
18
20
|
end
|
19
21
|
|
22
|
+
private
|
23
|
+
|
20
24
|
def autocorrect(node)
|
21
|
-
|
22
|
-
|
23
|
-
->(corrector) { corrector.replace(node.source_range, oneline) }
|
24
|
-
end
|
25
|
+
oneline = "#{node.body.source} #{node.keyword} " \
|
26
|
+
"#{node.condition.source}"
|
25
27
|
|
26
|
-
|
28
|
+
lambda do |corrector|
|
29
|
+
corrector.replace(node.source_range, oneline)
|
30
|
+
end
|
31
|
+
end
|
27
32
|
|
28
33
|
def check(node)
|
29
|
-
return unless node.
|
30
|
-
return unless single_line_as_modifier?(node)
|
31
|
-
add_offense(node, :keyword, message(node.loc.keyword.source))
|
32
|
-
end
|
34
|
+
return unless node.multiline? && single_line_as_modifier?(node)
|
33
35
|
|
34
|
-
|
35
|
-
"Favor modifier `#{keyword}` usage when having a single-line body."
|
36
|
+
add_offense(node, :keyword, format(MSG, node.keyword))
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
@@ -18,7 +18,7 @@ module RuboCop
|
|
18
18
|
def on_array(node)
|
19
19
|
if bracketed_array_of?(:str, node)
|
20
20
|
check_bracketed(node)
|
21
|
-
elsif
|
21
|
+
elsif node.percent_literal?(:string)
|
22
22
|
check_percent(node)
|
23
23
|
end
|
24
24
|
end
|
@@ -34,21 +34,17 @@ module RuboCop
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def check_bracketed(node)
|
37
|
-
|
38
|
-
|
39
|
-
return if complex_content?(array_elems) ||
|
37
|
+
return if complex_content?(node.values) ||
|
40
38
|
comments_in_array?(node)
|
41
|
-
style_detected(:brackets,
|
39
|
+
style_detected(:brackets, node.values.size)
|
42
40
|
|
43
|
-
return unless style == :percent &&
|
41
|
+
return unless style == :percent && node.values.size >= min_size
|
44
42
|
|
45
43
|
add_offense(node, :expression, PERCENT_MSG)
|
46
44
|
end
|
47
45
|
|
48
46
|
def check_percent(node)
|
49
|
-
|
50
|
-
|
51
|
-
style_detected(:percent, array_elems.size)
|
47
|
+
style_detected(:percent, node.values.size)
|
52
48
|
add_offense(node, :expression, ARRAY_MSG) if style == :brackets
|
53
49
|
end
|
54
50
|
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -52,7 +52,8 @@ module RuboCop
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def cops
|
55
|
-
|
55
|
+
only_options = @options.fetch(:only, [])
|
56
|
+
@cops ||= @cop_classes.enabled(@config, only_options).map do |cop_class|
|
56
57
|
cop_class.new(@config, @options)
|
57
58
|
end
|
58
59
|
end
|
@@ -123,11 +124,6 @@ module RuboCop
|
|
123
124
|
Investigation.new(offenses, commissioner.errors)
|
124
125
|
end
|
125
126
|
|
126
|
-
def cop_enabled?(cop_class)
|
127
|
-
@config.cop_enabled?(cop_class) ||
|
128
|
-
(@options[:only] || []).include?(cop_class.cop_name)
|
129
|
-
end
|
130
|
-
|
131
127
|
def autocorrect_all_cops(buffer, cops)
|
132
128
|
corrector = Corrector.new(buffer)
|
133
129
|
skip = Set.new
|
@@ -155,27 +151,32 @@ module RuboCop
|
|
155
151
|
|
156
152
|
def process_commissioner_errors(file, file_errors)
|
157
153
|
file_errors.each do |cop, errors|
|
158
|
-
errors.each do |
|
154
|
+
errors.each do |cop_error|
|
155
|
+
e = cop_error.error
|
156
|
+
line = ":#{cop_error.line}" if cop_error.line
|
157
|
+
column = ":#{cop_error.column}" if cop_error.column
|
158
|
+
location = "#{file}#{line}#{column}"
|
159
|
+
|
159
160
|
if e.is_a?(Warning)
|
160
|
-
handle_warning(e,
|
161
|
-
Rainbow("#{e.message} (from file: " \
|
162
|
-
"#{file})").yellow)
|
161
|
+
handle_warning(e, location)
|
163
162
|
else
|
164
|
-
handle_error(e,
|
165
|
-
Rainbow("An error occurred while #{cop.name}" \
|
166
|
-
" cop was inspecting #{file}.").red)
|
163
|
+
handle_error(e, location, cop)
|
167
164
|
end
|
168
165
|
end
|
169
166
|
end
|
170
167
|
end
|
171
168
|
|
172
|
-
def handle_warning(e,
|
169
|
+
def handle_warning(e, location)
|
170
|
+
message = Rainbow("#{e.message} (from file: #{location})").yellow
|
171
|
+
|
173
172
|
@warnings << message
|
174
173
|
warn message
|
175
174
|
puts e.backtrace if debug?
|
176
175
|
end
|
177
176
|
|
178
|
-
def handle_error(e,
|
177
|
+
def handle_error(e, location, cop)
|
178
|
+
message = Rainbow("An error occurred while #{cop.name}" \
|
179
|
+
" cop was inspecting #{location}.").red
|
179
180
|
@errors << message
|
180
181
|
warn message
|
181
182
|
if debug?
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# This module contains a collection of useful utility methods.
|
7
7
|
module Util
|
8
8
|
include PathUtil
|
9
|
-
extend RuboCop::Sexp
|
9
|
+
extend RuboCop::AST::Sexp
|
10
10
|
|
11
11
|
BYTE_ORDER_MARK = 0xfeff # The Unicode codepoint
|
12
12
|
|
@@ -15,6 +15,10 @@ module RuboCop
|
|
15
15
|
SHORTHAND_ASGN_NODES = [:op_asgn, :or_asgn, :and_asgn].freeze
|
16
16
|
ASGN_NODES = (EQUALS_ASGN_NODES + SHORTHAND_ASGN_NODES).freeze
|
17
17
|
|
18
|
+
MODIFIER_NODES = [:if, :while, :until].freeze
|
19
|
+
CONDITIONAL_NODES = (MODIFIER_NODES + [:case]).freeze
|
20
|
+
LOGICAL_OPERATOR_NODES = [:and, :or].freeze
|
21
|
+
|
18
22
|
# http://phrogz.net/programmingruby/language.html#table_18.4
|
19
23
|
# Backtick is added last just to help editors parse this code.
|
20
24
|
OPERATOR_METHODS = %w(
|
@@ -172,8 +176,8 @@ module RuboCop
|
|
172
176
|
end
|
173
177
|
|
174
178
|
def within_node?(inner, outer)
|
175
|
-
o = outer.is_a?(Node) ? outer.source_range : outer
|
176
|
-
i = inner.is_a?(Node) ? inner.source_range : inner
|
179
|
+
o = outer.is_a?(AST::Node) ? outer.source_range : outer
|
180
|
+
i = inner.is_a?(AST::Node) ? inner.source_range : inner
|
177
181
|
i.begin_pos >= o.begin_pos && i.end_pos <= o.end_pos
|
178
182
|
end
|
179
183
|
|
@@ -271,6 +275,12 @@ module RuboCop
|
|
271
275
|
src = src.dup if RUBY_VERSION < '2.3'
|
272
276
|
src.force_encoding(Encoding.default_external).valid_encoding?
|
273
277
|
end
|
278
|
+
|
279
|
+
def to_supported_styles(enforced_style)
|
280
|
+
enforced_style
|
281
|
+
.sub(/^Enforced/, 'Supported')
|
282
|
+
.sub('Style', 'Styles')
|
283
|
+
end
|
274
284
|
end
|
275
285
|
end
|
276
286
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# The precise location of the problem is shown together with the
|
7
7
|
# relevant source code.
|
8
8
|
class ClangStyleFormatter < SimpleTextFormatter
|
9
|
-
ELLIPSES =
|
9
|
+
ELLIPSES = '...'.freeze
|
10
10
|
|
11
11
|
def report_file(file, offenses)
|
12
12
|
offenses.each { |offense| report_offense(file, offense) }
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
if location.first_line == location.last_line
|
42
42
|
output.puts(source_line)
|
43
43
|
else
|
44
|
-
output.puts("#{source_line} #{ELLIPSES}")
|
44
|
+
output.puts("#{source_line} #{yellow(ELLIPSES)}")
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -18,7 +18,7 @@ module RuboCop
|
|
18
18
|
@config_to_allow_offenses = {}
|
19
19
|
@detected_styles = {}
|
20
20
|
|
21
|
-
COPS = Cop::Cop.
|
21
|
+
COPS = Cop::Cop.registry.to_h
|
22
22
|
|
23
23
|
class << self
|
24
24
|
attr_accessor :config_to_allow_offenses, :detected_styles
|
@@ -66,6 +66,7 @@ module RuboCop
|
|
66
66
|
if @exclude_limit_option
|
67
67
|
command += format(' --exclude-limit %d', @exclude_limit_option.to_i)
|
68
68
|
end
|
69
|
+
command += ' --no-offense-counts' if @options[:no_offense_counts]
|
69
70
|
|
70
71
|
command
|
71
72
|
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# Parse different formats of magic comments.
|
5
|
+
#
|
6
|
+
# @abstract parent of three different magic comment handlers
|
7
|
+
class MagicComment
|
8
|
+
# @see https://git.io/vMC1C IRB's pattern for matching magic comment tokens
|
9
|
+
TOKEN = /[[:alnum:]\-_]+/
|
10
|
+
|
11
|
+
# Detect magic comment format and pass it to the appropriate wrapper.
|
12
|
+
#
|
13
|
+
# @param comment [String]
|
14
|
+
#
|
15
|
+
# @return [RuboCop::MagicComment]
|
16
|
+
def self.parse(comment)
|
17
|
+
case comment
|
18
|
+
when EmacsComment::FORMAT then EmacsComment.new(comment)
|
19
|
+
when VimComment::FORMAT then VimComment.new(comment)
|
20
|
+
else
|
21
|
+
SimpleComment.new(comment)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(comment)
|
26
|
+
@comment = comment
|
27
|
+
end
|
28
|
+
|
29
|
+
# Does the magic comment enable the frozen string literal feature.
|
30
|
+
#
|
31
|
+
# Test whether the frozen string literal value is `true`. Cannot
|
32
|
+
# just return `frozen_string_literal` since an invalid magic comment
|
33
|
+
# like `# frozen_string_literal: yes` is possible and the truthy value
|
34
|
+
# `'yes'` does not actually enable the feature
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
def frozen_string_literal?
|
38
|
+
frozen_string_literal == true
|
39
|
+
end
|
40
|
+
|
41
|
+
# Was a magic comment for the frozen string literal found?
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
def frozen_string_literal_specified?
|
45
|
+
!frozen_string_literal.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Expose the `frozen_string_literal` value coerced to a boolean if possible.
|
49
|
+
#
|
50
|
+
# @return [Boolean] if value is `true` or `false`
|
51
|
+
# @return [nil] if frozen_string_literal comment isn't found
|
52
|
+
# @return [String] if comment is found but isn't true or false
|
53
|
+
def frozen_string_literal
|
54
|
+
return unless (setting = extract_frozen_string_literal)
|
55
|
+
|
56
|
+
case setting
|
57
|
+
when 'true' then true
|
58
|
+
when 'false' then false
|
59
|
+
else
|
60
|
+
setting
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Match the entire comment string with a pattern and take the first capture.
|
67
|
+
#
|
68
|
+
# @param pattern [Regexp]
|
69
|
+
#
|
70
|
+
# @return [String] if pattern matched
|
71
|
+
# @return [nil] otherwise
|
72
|
+
def extract(pattern)
|
73
|
+
@comment[pattern, 1]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Parent to Vim and Emacs magic comment handling.
|
77
|
+
#
|
78
|
+
# @abstract
|
79
|
+
class EditorComment < MagicComment
|
80
|
+
private
|
81
|
+
|
82
|
+
# Find a token starting with the provided keyword and extract its value.
|
83
|
+
#
|
84
|
+
# @param keyword [String]
|
85
|
+
#
|
86
|
+
# @return [String] extracted value if it is found
|
87
|
+
# @return [nil] otherwise
|
88
|
+
def match(keyword)
|
89
|
+
pattern = /\A#{keyword}\s*#{self.class::OPERATOR}\s*(#{TOKEN})\z/
|
90
|
+
|
91
|
+
tokens.each do |token|
|
92
|
+
next unless (value = token[pattern, 1])
|
93
|
+
|
94
|
+
return value.downcase
|
95
|
+
end
|
96
|
+
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
# Individual tokens composing an editor specific comment string.
|
101
|
+
#
|
102
|
+
# @return [Array<String>]
|
103
|
+
def tokens
|
104
|
+
extract(self.class::FORMAT).split(self.class::SEPARATOR).map(&:strip)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Wrapper for Emacs style magic comments.
|
109
|
+
#
|
110
|
+
# @example Emacs style comment
|
111
|
+
# comment = RuboCop::MagicComment.parse(
|
112
|
+
# '# -*- encoding: ASCII-8BIT; frozen_string_literal: true -*-'
|
113
|
+
# )
|
114
|
+
#
|
115
|
+
# comment.encoding # => 'ascii-8bit'
|
116
|
+
# comment.frozen_string_literal # => true
|
117
|
+
#
|
118
|
+
# @see https://www.gnu.org/software/emacs/manual/html_node/emacs/Specify-Coding.html
|
119
|
+
# @see https://git.io/vMCXh Emacs handling in Ruby's parse.y
|
120
|
+
class EmacsComment < EditorComment
|
121
|
+
FORMAT = /\-\*\-(.+)\-\*\-/
|
122
|
+
SEPARATOR = ';'.freeze
|
123
|
+
OPERATOR = ':'.freeze
|
124
|
+
|
125
|
+
def encoding
|
126
|
+
match('encoding')
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def extract_frozen_string_literal
|
132
|
+
match('frozen_string_literal')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Wrapper for Vim style magic comments.
|
137
|
+
#
|
138
|
+
# @example Vim style comment
|
139
|
+
# comment = RuboCop::MagicComment.parse(
|
140
|
+
# '# vim: filetype=ruby, fileencoding=ascii-8bit'
|
141
|
+
# )
|
142
|
+
#
|
143
|
+
# comment.encoding # => 'ascii-8bit'
|
144
|
+
class VimComment < EditorComment
|
145
|
+
FORMAT = /#\s*vim:\s*(.+)/
|
146
|
+
SEPARATOR = ', '.freeze
|
147
|
+
OPERATOR = '='.freeze
|
148
|
+
|
149
|
+
# For some reason the fileencoding keyword only works if there
|
150
|
+
# is at least one other token included in the string. For example
|
151
|
+
#
|
152
|
+
# # works
|
153
|
+
# # vim: foo=bar, fileencoding=ascii-8bit
|
154
|
+
#
|
155
|
+
# # does nothing
|
156
|
+
# # vim: foo=bar, fileencoding=ascii-8bit
|
157
|
+
#
|
158
|
+
def encoding
|
159
|
+
match('fileencoding') if tokens.size > 1
|
160
|
+
end
|
161
|
+
|
162
|
+
# Vim comments cannot specify frozen string literal behavior.
|
163
|
+
def frozen_string_literal; end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Wrapper for regular magic comments not bound to an editor.
|
167
|
+
#
|
168
|
+
# Simple comments can only specify one setting per comment.
|
169
|
+
#
|
170
|
+
# @example frozen string literal comments
|
171
|
+
# comment1 = RuboCop::MagicComment.parse('# frozen_string_literal: true')
|
172
|
+
# comment1.frozen_string_literal # => true
|
173
|
+
# comment1.encoding # => nil
|
174
|
+
#
|
175
|
+
# @example encoding comments
|
176
|
+
# comment2 = RuboCop::MagicComment.parse('# encoding: utf-8')
|
177
|
+
# comment2.frozen_string_literal # => nil
|
178
|
+
# comment2.encoding # => 'utf-8'
|
179
|
+
class SimpleComment < MagicComment
|
180
|
+
# Match `encoding` or `coding`
|
181
|
+
def encoding
|
182
|
+
extract(/\b(?:en)?coding: (#{TOKEN})/)
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
# Extract `frozen_string_literal`.
|
188
|
+
#
|
189
|
+
# The `frozen_string_literal` magic comment only works if it
|
190
|
+
# is the only text in the comment.
|
191
|
+
def extract_frozen_string_literal
|
192
|
+
extract(/^#\s*frozen_string_literal:\s*(#{TOKEN})\s*$/)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
data/lib/rubocop/options.rb
CHANGED
@@ -179,13 +179,14 @@ module RuboCop
|
|
179
179
|
def self.validate_cop_list(names)
|
180
180
|
return unless names
|
181
181
|
|
182
|
-
|
182
|
+
departments = Cop::Cop.registry.departments.map(&:to_s)
|
183
|
+
|
183
184
|
names.each do |name|
|
184
|
-
next if Cop::Cop.
|
185
|
-
next if
|
185
|
+
next if Cop::Cop.registry.names.include?(name)
|
186
|
+
next if departments.include?(name)
|
186
187
|
next if %w(Syntax Lint/Syntax).include?(name)
|
187
188
|
|
188
|
-
raise ArgumentError, "Unrecognized cop or
|
189
|
+
raise ArgumentError, "Unrecognized cop or department: #{name}."
|
189
190
|
end
|
190
191
|
end
|
191
192
|
|
@@ -133,7 +133,7 @@ module RuboCop
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def create_parser(ruby_version)
|
136
|
-
builder = RuboCop::
|
136
|
+
builder = RuboCop::AST::Builder.new
|
137
137
|
|
138
138
|
parser_class(ruby_version).new(builder).tap do |parser|
|
139
139
|
# On JRuby and Rubinius, there's a risk that we hang in tokenize() if we
|
@@ -53,6 +53,15 @@ module CopHelper
|
|
53
53
|
corrector.rewrite
|
54
54
|
end
|
55
55
|
|
56
|
+
def autocorrect_source_with_loop(cop, source, file = nil)
|
57
|
+
loop do
|
58
|
+
cop.instance_variable_set(:@corrections, [])
|
59
|
+
new_source = autocorrect_source(cop, source, file)
|
60
|
+
return new_source if new_source == source
|
61
|
+
source = new_source
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
56
65
|
def _investigate(cop, processed_source)
|
57
66
|
forces = RuboCop::Cop::Force.all.each_with_object([]) do |klass, instances|
|
58
67
|
next unless cop.join_force?(klass)
|