rubocop 0.79.0 → 0.83.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +5 -5
- data/config/default.yml +184 -50
- data/lib/rubocop.rb +15 -5
- data/lib/rubocop/ast/builder.rb +2 -0
- data/lib/rubocop/ast/node.rb +12 -19
- data/lib/rubocop/ast/node/array_node.rb +13 -0
- data/lib/rubocop/ast/node/block_node.rb +5 -1
- data/lib/rubocop/ast/node/case_match_node.rb +56 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +8 -0
- data/lib/rubocop/ast/node/regexp_node.rb +2 -4
- data/lib/rubocop/ast/node/send_node.rb +4 -0
- data/lib/rubocop/ast/traversal.rb +20 -9
- data/lib/rubocop/cli.rb +11 -5
- data/lib/rubocop/comment_config.rb +6 -1
- data/lib/rubocop/config.rb +40 -10
- data/lib/rubocop/config_loader.rb +43 -33
- data/lib/rubocop/config_loader_resolver.rb +28 -1
- data/lib/rubocop/config_obsoletion.rb +4 -1
- data/lib/rubocop/config_validator.rb +18 -1
- data/lib/rubocop/cop/badge.rb +5 -5
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
- data/lib/rubocop/cop/corrector.rb +48 -24
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -2
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/generator.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/array_alignment.rb +53 -10
- data/lib/rubocop/cop/layout/block_end_newline.rb +5 -3
- data/lib/rubocop/cop/layout/condition_position.rb +12 -2
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +8 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +68 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +16 -10
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/{tab.rb → indentation_style.rb} +48 -6
- data/lib/rubocop/cop/layout/leading_comment_space.rb +34 -3
- data/lib/rubocop/cop/layout/line_length.rb +36 -4
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +13 -4
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +3 -3
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +133 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +37 -2
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +2 -2
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +38 -0
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +14 -0
- data/lib/rubocop/cop/lint/boolean_symbol.rb +12 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -5
- data/lib/rubocop/cop/lint/empty_when.rb +29 -6
- data/lib/rubocop/cop/lint/ensure_return.rb +18 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +10 -13
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/loop.rb +6 -4
- data/lib/rubocop/cop/lint/multiple_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +2 -2
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +21 -9
- data/lib/rubocop/cop/lint/percent_string_array.rb +2 -2
- data/lib/rubocop/cop/lint/raise_exception.rb +75 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -6
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +58 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +12 -28
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -2
- data/lib/rubocop/cop/lint/unused_method_argument.rb +32 -6
- data/lib/rubocop/cop/lint/uri_regexp.rb +4 -4
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -2
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +5 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -0
- data/lib/rubocop/cop/migration/department_name.rb +36 -10
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +6 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +16 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +178 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +2 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +5 -0
- data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -22
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -10
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +26 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/registry.rb +11 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -6
- data/lib/rubocop/cop/style/alias.rb +4 -4
- data/lib/rubocop/cop/style/and_or.rb +5 -6
- data/lib/rubocop/cop/style/array_join.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
- data/lib/rubocop/cop/style/case_equality.rb +24 -1
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -8
- data/lib/rubocop/cop/style/copyright.rb +1 -1
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +49 -0
- data/lib/rubocop/cop/style/documentation.rb +43 -5
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +3 -3
- data/lib/rubocop/cop/style/empty_method.rb +1 -5
- data/lib/rubocop/cop/style/end_block.rb +6 -0
- data/lib/rubocop/cop/style/even_odd.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +119 -0
- data/lib/rubocop/cop/style/format_string.rb +2 -2
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
- data/lib/rubocop/cop/style/guard_clause.rb +25 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +89 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +83 -0
- data/lib/rubocop/cop/style/hash_transform_values.rb +80 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +23 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
- data/lib/rubocop/cop/style/lambda.rb +3 -2
- data/lib/rubocop/cop/style/lambda_call.rb +1 -21
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +5 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +5 -4
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +58 -12
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +1 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +16 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +2 -4
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -4
- data/lib/rubocop/cop/style/next.rb +2 -2
- data/lib/rubocop/cop/style/nil_comparison.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +4 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
- data/lib/rubocop/cop/style/or_assignment.rb +4 -3
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/perl_backrefs.rb +2 -2
- data/lib/rubocop/cop/style/proc.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +18 -6
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +3 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
- data/lib/rubocop/cop/style/redundant_return.rb +5 -7
- data/lib/rubocop/cop/style/redundant_self.rb +1 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +39 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -4
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -1
- data/lib/rubocop/cop/style/symbol_array.rb +3 -3
- data/lib/rubocop/cop/style/symbol_literal.rb +2 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +35 -22
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +41 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +88 -0
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +44 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +0 -4
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
- data/lib/rubocop/cop/util.rb +24 -0
- data/lib/rubocop/cop/variable_force.rb +4 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -0
- data/lib/rubocop/cop/variable_force/scope.rb +1 -0
- data/lib/rubocop/cop/variable_force/variable.rb +1 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +74 -0
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/name_similarity.rb +12 -9
- data/lib/rubocop/node_pattern.rb +96 -10
- data/lib/rubocop/options.rb +18 -5
- data/lib/rubocop/processed_source.rb +1 -4
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +0 -4
- data/lib/rubocop/runner.rb +7 -2
- data/lib/rubocop/target_finder.rb +6 -4
- data/lib/rubocop/target_ruby.rb +2 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +35 -25
- data/lib/rubocop/cop/lint/end_in_method.rb +0 -40
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
- data/lib/rubocop/formatter/disabled_lines_formatter.rb +0 -57
- data/lib/rubocop/string_util.rb +0 -14
data/lib/rubocop/cop/util.rb
CHANGED
@@ -17,6 +17,10 @@ module RuboCop
|
|
17
17
|
line_source =~ /^\s*#/
|
18
18
|
end
|
19
19
|
|
20
|
+
def comment_lines?(node)
|
21
|
+
processed_source[line_range(node)].any? { |line| comment_line?(line) }
|
22
|
+
end
|
23
|
+
|
20
24
|
def line_range(node)
|
21
25
|
node.first_line..node.last_line
|
22
26
|
end
|
@@ -26,6 +30,26 @@ module RuboCop
|
|
26
30
|
node.loc.end.is?(')')
|
27
31
|
end
|
28
32
|
|
33
|
+
def add_parentheses(node, corrector)
|
34
|
+
if node.arguments.empty?
|
35
|
+
corrector.insert_after(node, '()')
|
36
|
+
else
|
37
|
+
corrector.replace(args_begin(node), '(')
|
38
|
+
corrector.insert_after(args_end(node), ')')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def args_begin(node)
|
43
|
+
loc = node.loc
|
44
|
+
selector =
|
45
|
+
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
|
46
|
+
selector.end.resize(1)
|
47
|
+
end
|
48
|
+
|
49
|
+
def args_end(node)
|
50
|
+
node.loc.expression.end
|
51
|
+
end
|
52
|
+
|
29
53
|
def on_node(syms, sexp, excludes = [], &block)
|
30
54
|
return to_enum(:on_node, syms, sexp, excludes) unless block_given?
|
31
55
|
|
@@ -190,7 +190,10 @@ module RuboCop
|
|
190
190
|
end
|
191
191
|
|
192
192
|
def regexp_captured_names(node)
|
193
|
-
regexp_string = node.children
|
193
|
+
regexp_string = node.children.select(&:str_type?).map do |child|
|
194
|
+
child.children.first
|
195
|
+
end.join || ''
|
196
|
+
|
194
197
|
regexp = Regexp.new(regexp_string)
|
195
198
|
|
196
199
|
regexp.named_captures.keys
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
report_line(offense.location)
|
31
31
|
report_highlighted_area(offense.highlighted_area)
|
32
|
-
rescue IndexError
|
32
|
+
rescue IndexError
|
33
33
|
# range is not on a valid line; perhaps the source file is empty
|
34
34
|
end
|
35
35
|
end
|
@@ -11,12 +11,12 @@ module RuboCop
|
|
11
11
|
BUILTIN_FORMATTERS_FOR_KEYS = {
|
12
12
|
'[a]utogenconf' => AutoGenConfigFormatter,
|
13
13
|
'[c]lang' => ClangStyleFormatter,
|
14
|
-
'[d]isabled' => DisabledLinesFormatter,
|
15
14
|
'[e]macs' => EmacsStyleFormatter,
|
16
15
|
'[fi]les' => FileListFormatter,
|
17
16
|
'[fu]ubar' => FuubarStyleFormatter,
|
18
17
|
'[h]tml' => HTMLFormatter,
|
19
18
|
'[j]son' => JSONFormatter,
|
19
|
+
'[ju]nit' => JUnitFormatter,
|
20
20
|
'[o]ffenses' => OffenseCountFormatter,
|
21
21
|
'[pa]cman' => PacmanFormatter,
|
22
22
|
'[p]rogress' => ProgressFormatter,
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
#
|
6
|
+
# This code is based on https://github.com/mikian/rubocop-junit-formatter.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2015 Mikko Kokkonen
|
9
|
+
#
|
10
|
+
# MIT License
|
11
|
+
#
|
12
|
+
# https://github.com/mikian/rubocop-junit-formatter/blob/master/LICENSE.txt
|
13
|
+
#
|
14
|
+
module RuboCop
|
15
|
+
module Formatter
|
16
|
+
# This formatter formats the report data in JUnit format.
|
17
|
+
class JUnitFormatter < BaseFormatter
|
18
|
+
def initialize(output, options = {})
|
19
|
+
super
|
20
|
+
|
21
|
+
@document = REXML::Document.new.tap do |document|
|
22
|
+
document << REXML::XMLDecl.new
|
23
|
+
end
|
24
|
+
testsuites = REXML::Element.new('testsuites', @document)
|
25
|
+
testsuite = REXML::Element.new('testsuite', testsuites)
|
26
|
+
@testsuite = testsuite.tap do |element|
|
27
|
+
element.add_attributes('name' => 'rubocop')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def file_finished(file, offenses)
|
32
|
+
# TODO: Returns all cops with the same behavior as
|
33
|
+
# the original rubocop-junit-formatter.
|
34
|
+
# https://github.com/mikian/rubocop-junit-formatter/blob/v0.1.4/lib/rubocop/formatter/junit_formatter.rb#L9
|
35
|
+
#
|
36
|
+
# In the future, it would be preferable to return only enabled cops.
|
37
|
+
Cop::Cop.all.each do |cop|
|
38
|
+
REXML::Element.new('testcase', @testsuite).tap do |testcase|
|
39
|
+
testcase.attributes['classname'] = classname_attribute_value(file)
|
40
|
+
testcase.attributes['name'] = cop.cop_name
|
41
|
+
|
42
|
+
target_offenses = offenses.select do |offense|
|
43
|
+
offense.cop_name == cop.cop_name
|
44
|
+
end
|
45
|
+
|
46
|
+
add_failure_to(testcase, target_offenses, cop.cop_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def classname_attribute_value(file)
|
52
|
+
file.gsub(/\.rb\Z/, '').gsub("#{Dir.pwd}/", '').tr('/', '.')
|
53
|
+
end
|
54
|
+
|
55
|
+
def finished(_inspected_files)
|
56
|
+
@document.write(output, 2)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def add_failure_to(testcase, offenses, cop_name)
|
62
|
+
# One failure per offense. Zero failures is a passing test case,
|
63
|
+
# for most surefire/nUnit parsers.
|
64
|
+
offenses.each do |offense|
|
65
|
+
REXML::Element.new('failure', testcase).tap do |failure|
|
66
|
+
failure.attributes['type'] = cop_name
|
67
|
+
failure.attributes['message'] = offense.message
|
68
|
+
failure.add_text(offense.location.to_s)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -69,7 +69,7 @@ module RuboCop
|
|
69
69
|
regex = /#{Regexp.quote(PACMAN)}|#{Regexp.quote(PACDOT)}/
|
70
70
|
@progress_line = @progress_line.sub(regex, character)
|
71
71
|
output.printf("%<line>s\r", line: @progress_line)
|
72
|
-
return unless @progress_line[-1]
|
72
|
+
return unless /ᗣ|\./.match?(@progress_line[-1])
|
73
73
|
|
74
74
|
@repetitions += 1
|
75
75
|
output.puts
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
|
57
57
|
report_line(offense.location)
|
58
58
|
report_highlighted_area(offense.highlighted_area)
|
59
|
-
rescue IndexError
|
59
|
+
rescue IndexError
|
60
60
|
# range is not on a valid line; perhaps the source file is empty
|
61
61
|
end
|
62
62
|
end
|
@@ -3,19 +3,22 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# Common functionality for finding names that are similar to a given name.
|
5
5
|
module NameSimilarity
|
6
|
-
|
6
|
+
module_function
|
7
7
|
|
8
|
-
def find_similar_name(target_name,
|
9
|
-
|
8
|
+
def find_similar_name(target_name, names)
|
9
|
+
similar_names = find_similar_names(target_name, names)
|
10
|
+
|
11
|
+
similar_names.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_similar_names(target_name, names)
|
15
|
+
names = names.dup
|
10
16
|
names.delete(target_name)
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
hash[name] = score if score >= MINIMUM_SIMILARITY_TO_SUGGEST
|
15
|
-
end
|
18
|
+
spell_checker = DidYouMean::SpellChecker.new(dictionary: names)
|
19
|
+
similar_names = spell_checker.correct(target_name)
|
16
20
|
|
17
|
-
|
18
|
-
most_similar_name
|
21
|
+
similar_names
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
data/lib/rubocop/node_pattern.rb
CHANGED
@@ -78,6 +78,8 @@ module RuboCop
|
|
78
78
|
# # matching process starts
|
79
79
|
# '^^send' # each ^ ascends one level in the AST
|
80
80
|
# # so this matches against the grandparent node
|
81
|
+
# '`send' # descends any number of level in the AST
|
82
|
+
# # so this matches against any descendant node
|
81
83
|
# '#method' # we call this a 'funcall'; it calls a method in the
|
82
84
|
# # context where a pattern-matching method is defined
|
83
85
|
# # if that returns a truthy value, the match succeeds
|
@@ -112,7 +114,7 @@ module RuboCop
|
|
112
114
|
SYMBOL = %r{:(?:[\w+@*/?!<>=~|%^-]+|\[\]=?)}.freeze
|
113
115
|
IDENTIFIER = /[a-zA-Z_][a-zA-Z0-9_-]*/.freeze
|
114
116
|
META = Regexp.union(
|
115
|
-
%w"( ) { } [ ] $< < > $... $ ! ^ ... + * ?"
|
117
|
+
%w"( ) { } [ ] $< < > $... $ ! ^ ` ... + * ?"
|
116
118
|
).freeze
|
117
119
|
NUMBER = /-?\d+(?:\.\d+)?/.freeze
|
118
120
|
STRING = /".+?"/.freeze
|
@@ -188,7 +190,7 @@ module RuboCop
|
|
188
190
|
|
189
191
|
@temps = 0 # avoid name clashes between temp variables
|
190
192
|
@captures = 0 # number of captures seen
|
191
|
-
@unify = {} # named wildcard -> temp variable
|
193
|
+
@unify = {} # named wildcard -> temp variable
|
192
194
|
@params = 0 # highest % (param) number seen
|
193
195
|
run(node_var)
|
194
196
|
end
|
@@ -223,6 +225,7 @@ module RuboCop
|
|
223
225
|
when '!' then compile_negation
|
224
226
|
when '$' then compile_capture
|
225
227
|
when '^' then compile_ascend
|
228
|
+
when '`' then compile_descend
|
226
229
|
when WILDCARD then compile_wildcard(token[1..-1])
|
227
230
|
when FUNCALL then compile_funcall(token)
|
228
231
|
when LITERAL then compile_literal(token)
|
@@ -466,12 +469,67 @@ module RuboCop
|
|
466
469
|
end
|
467
470
|
end
|
468
471
|
|
472
|
+
def access_unify(name)
|
473
|
+
var = @unify[name]
|
474
|
+
|
475
|
+
if var == :forbidden_unification
|
476
|
+
fail_due_to "Wildcard #{name} was first seen in a subset of a" \
|
477
|
+
" union and can't be used outside that union"
|
478
|
+
end
|
479
|
+
var
|
480
|
+
end
|
481
|
+
|
482
|
+
def forbid_unification(*names)
|
483
|
+
names.each do |name|
|
484
|
+
@unify[name] = :forbidden_unification
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
489
|
+
def unify_in_union(enum)
|
490
|
+
# We need to reset @unify before each branch is processed.
|
491
|
+
# Moreover we need to keep track of newly encountered wildcards.
|
492
|
+
# Var `new_unify_intersection` will hold those that are encountered
|
493
|
+
# in all branches; these are not a problem.
|
494
|
+
# Var `partial_unify` will hold those encountered in only a subset
|
495
|
+
# of the branches; these can't be used outside of the union.
|
496
|
+
|
497
|
+
return to_enum __method__, enum unless block_given?
|
498
|
+
|
499
|
+
new_unify_intersection = nil
|
500
|
+
partial_unify = []
|
501
|
+
unify_before = @unify.dup
|
502
|
+
|
503
|
+
result = enum.each do |e|
|
504
|
+
@unify = unify_before.dup if new_unify_intersection
|
505
|
+
yield e
|
506
|
+
new_unify = @unify.keys - unify_before.keys
|
507
|
+
if new_unify_intersection.nil?
|
508
|
+
# First iteration
|
509
|
+
new_unify_intersection = new_unify
|
510
|
+
else
|
511
|
+
union = new_unify_intersection | new_unify
|
512
|
+
new_unify_intersection &= new_unify
|
513
|
+
partial_unify |= union - new_unify_intersection
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
# At this point, all members of `new_unify_intersection` can be used
|
518
|
+
# for unification outside of the union, but partial_unify may not
|
519
|
+
|
520
|
+
forbid_unification(*partial_unify)
|
521
|
+
|
522
|
+
result
|
523
|
+
end
|
524
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
525
|
+
|
469
526
|
def compile_union
|
470
527
|
# we need to ensure that each branch of the {} contains the same
|
471
528
|
# number of captures (since only one branch of the {} can actually
|
472
529
|
# match, the same variables are used to hold the captures for each
|
473
530
|
# branch)
|
474
531
|
enum = tokens_until('}', 'union')
|
532
|
+
enum = unify_in_union(enum)
|
475
533
|
terms = insure_same_captures(enum, 'branch of {}')
|
476
534
|
.map { compile_expr }
|
477
535
|
|
@@ -496,6 +554,19 @@ module RuboCop
|
|
496
554
|
with_context("#{CUR_NODE} && #{compile_expr}", "#{CUR_NODE}.parent")
|
497
555
|
end
|
498
556
|
|
557
|
+
def compile_descend
|
558
|
+
with_temp_variables do |descendant|
|
559
|
+
pattern = with_context(compile_expr, descendant,
|
560
|
+
use_temp_node: false)
|
561
|
+
[
|
562
|
+
"RuboCop::NodePattern.descend(#{CUR_ELEMENT}).",
|
563
|
+
"any? do |#{descendant}|",
|
564
|
+
" #{pattern}",
|
565
|
+
'end'
|
566
|
+
].join("\n")
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
499
570
|
def compile_wildcard(name)
|
500
571
|
if name.empty?
|
501
572
|
'true'
|
@@ -503,12 +574,12 @@ module RuboCop
|
|
503
574
|
# we have already seen a wildcard with this name before
|
504
575
|
# so the value it matched the first time will already be stored
|
505
576
|
# in a temp. check if this value matches the one stored in the temp
|
506
|
-
"#{CUR_ELEMENT} ==
|
577
|
+
"#{CUR_ELEMENT} == #{access_unify(name)}"
|
507
578
|
else
|
508
|
-
n = @unify[name] =
|
509
|
-
# double assign to
|
510
|
-
"(
|
511
|
-
"
|
579
|
+
n = @unify[name] = "unify_#{name.gsub('-', '__')}"
|
580
|
+
# double assign to avoid "assigned but unused variable"
|
581
|
+
"(#{n} = #{CUR_ELEMENT}; " \
|
582
|
+
"#{n} = #{n}; true)"
|
512
583
|
end
|
513
584
|
end
|
514
585
|
|
@@ -560,9 +631,8 @@ module RuboCop
|
|
560
631
|
def compile_arg(token)
|
561
632
|
case token
|
562
633
|
when WILDCARD then
|
563
|
-
name
|
564
|
-
|
565
|
-
"temp#{number}"
|
634
|
+
name = token[1..-1]
|
635
|
+
access_unify(name) || fail_due_to('invalid in arglist: ' + token)
|
566
636
|
when LITERAL then token
|
567
637
|
when PARAM then get_param(token[1..-1])
|
568
638
|
when CLOSING then fail_due_to("#{token} in invalid position")
|
@@ -796,6 +866,22 @@ module RuboCop
|
|
796
866
|
def to_s
|
797
867
|
"#<#{self.class} #{pattern}>"
|
798
868
|
end
|
869
|
+
|
870
|
+
# Yields its argument and any descendants, depth-first.
|
871
|
+
#
|
872
|
+
def self.descend(element, &block)
|
873
|
+
return to_enum(__method__, element) unless block_given?
|
874
|
+
|
875
|
+
yield element
|
876
|
+
|
877
|
+
if element.is_a?(::RuboCop::AST::Node)
|
878
|
+
element.children.each do |child|
|
879
|
+
descend(child, &block)
|
880
|
+
end
|
881
|
+
end
|
882
|
+
|
883
|
+
nil
|
884
|
+
end
|
799
885
|
end
|
800
886
|
end
|
801
887
|
# rubocop:enable Metrics/ClassLength, Metrics/CyclomaticComplexity
|
data/lib/rubocop/options.rb
CHANGED
@@ -83,6 +83,12 @@ module RuboCop
|
|
83
83
|
|
84
84
|
def add_cop_selection_csv_option(option, opts)
|
85
85
|
option(opts, "--#{option} [COP1,COP2,...]") do |list|
|
86
|
+
unless list
|
87
|
+
message = "--#{option} argument should be [COP1,COP2,...]."
|
88
|
+
|
89
|
+
raise OptionArgumentError, message
|
90
|
+
end
|
91
|
+
|
86
92
|
@options[:"#{option}"] =
|
87
93
|
if list.empty?
|
88
94
|
['']
|
@@ -97,6 +103,7 @@ module RuboCop
|
|
97
103
|
def add_configuration_options(opts)
|
98
104
|
option(opts, '-c', '--config FILE')
|
99
105
|
option(opts, '--force-exclusion')
|
106
|
+
option(opts, '--only-recognized-file-types')
|
100
107
|
option(opts, '--ignore-parent-exclusion')
|
101
108
|
option(opts, '--force-default-config')
|
102
109
|
add_auto_gen_options(opts)
|
@@ -154,6 +161,7 @@ module RuboCop
|
|
154
161
|
end
|
155
162
|
end
|
156
163
|
|
164
|
+
# rubocop:disable Metrics/MethodLength
|
157
165
|
def add_boolean_flags(opts)
|
158
166
|
option(opts, '-F', '--fail-fast')
|
159
167
|
option(opts, '-C', '--cache FLAG')
|
@@ -162,6 +170,8 @@ module RuboCop
|
|
162
170
|
option(opts, '-E', '--extra-details')
|
163
171
|
option(opts, '-S', '--display-style-guide')
|
164
172
|
option(opts, '-a', '--auto-correct')
|
173
|
+
option(opts, '--disable-pending-cops')
|
174
|
+
option(opts, '--enable-pending-cops')
|
165
175
|
option(opts, '--ignore-disable-comments')
|
166
176
|
|
167
177
|
option(opts, '--safe')
|
@@ -172,6 +182,7 @@ module RuboCop
|
|
172
182
|
option(opts, '-V', '--verbose-version')
|
173
183
|
option(opts, '-P', '--parallel')
|
174
184
|
end
|
185
|
+
# rubocop:enable Metrics/MethodLength
|
175
186
|
|
176
187
|
def add_aliases(opts)
|
177
188
|
option(opts, '-l', '--lint') do
|
@@ -237,10 +248,7 @@ module RuboCop
|
|
237
248
|
def format_message_from(name, cop_names)
|
238
249
|
message = 'Unrecognized cop or department: %<name>s.'
|
239
250
|
message_with_candidate = "%<message>s\nDid you mean? %<candidate>s"
|
240
|
-
corrections =
|
241
|
-
score = StringUtil.similarity(cn, name)
|
242
|
-
score >= NameSimilarity::MINIMUM_SIMILARITY_TO_SUGGEST
|
243
|
-
end.sort
|
251
|
+
corrections = NameSimilarity.find_similar_names(name, cop_names)
|
244
252
|
|
245
253
|
if corrections.empty?
|
246
254
|
format(message, name: name)
|
@@ -362,7 +370,7 @@ module RuboCop
|
|
362
370
|
end
|
363
371
|
|
364
372
|
def validate_exclude_limit_option
|
365
|
-
return if @options[:exclude_limit]
|
373
|
+
return if /^\d+$/.match?(@options[:exclude_limit])
|
366
374
|
|
367
375
|
# Emulate OptionParser's behavior to make failures consistent regardless
|
368
376
|
# of option order.
|
@@ -405,6 +413,9 @@ module RuboCop
|
|
405
413
|
force_exclusion: ['Force excluding files specified in the',
|
406
414
|
'configuration `Exclude` even if they are',
|
407
415
|
'explicitly passed as arguments.'],
|
416
|
+
only_recognized_file_types: ['Inspect files given on the command line only if',
|
417
|
+
'they are listed in AllCops/Include parameters',
|
418
|
+
'of user configuration or default configuration.'],
|
408
419
|
ignore_disable_comments: ['Run cops even when they are disabled locally',
|
409
420
|
'with a comment.'],
|
410
421
|
ignore_parent_exclusion: ['Prevent from inheriting AllCops/Exclude from',
|
@@ -438,7 +449,9 @@ module RuboCop
|
|
438
449
|
debug: 'Display debug info.',
|
439
450
|
display_cop_names: ['Display cop names in offense messages.',
|
440
451
|
'Default is true.'],
|
452
|
+
disable_pending_cops: 'Run without pending cops.',
|
441
453
|
display_style_guide: 'Display style guide URLs in offense messages.',
|
454
|
+
enable_pending_cops: 'Run with pending cops.',
|
442
455
|
extra_details: 'Display extra details in offense messages.',
|
443
456
|
lint: 'Run only lint cops.',
|
444
457
|
safe: 'Run only safe cops.',
|