rubocop 0.85.0 → 0.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -17
- data/bin/rubocop-profile +31 -0
- data/config/default.yml +132 -11
- data/lib/rubocop.rb +17 -1
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/show_cops.rb +1 -1
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_loader.rb +39 -67
- data/lib/rubocop/config_loader_resolver.rb +1 -1
- data/lib/rubocop/config_obsoletion.rb +0 -1
- data/lib/rubocop/config_store.rb +4 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +14 -24
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +407 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
- data/lib/rubocop/cop/commissioner.rb +48 -50
- data/lib/rubocop/cop/cop.rb +91 -235
- data/lib/rubocop/cop/corrector.rb +38 -115
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +7 -2
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
- data/lib/rubocop/cop/layout/case_indentation.rb +18 -19
- data/lib/rubocop/cop/layout/class_structure.rb +2 -37
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -8
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/end_of_line.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +17 -7
- data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +22 -27
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +27 -68
- data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +4 -3
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
- data/lib/rubocop/cop/legacy/corrector.rb +29 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -4
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
- data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +3 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +13 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +8 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +14 -20
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +69 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -3
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +31 -25
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +2 -2
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +9 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +11 -26
- data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +22 -0
- data/lib/rubocop/cop/metrics/class_length.rb +25 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
- data/lib/rubocop/cop/metrics/method_length.rb +23 -0
- data/lib/rubocop/cop/metrics/module_length.rb +25 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +129 -0
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
- data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
- data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
- data/lib/rubocop/cop/mixin/code_length.rb +4 -0
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
- data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +1 -1
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +27 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +10 -5
- data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -13
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +6 -4
- data/lib/rubocop/cop/mixin/visibility_help.rb +50 -0
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +27 -4
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +3 -3
- data/lib/rubocop/cop/naming/file_name.rb +1 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +3 -5
- data/lib/rubocop/cop/naming/variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/variable_number.rb +1 -1
- data/lib/rubocop/cop/offense.rb +16 -2
- data/lib/rubocop/cop/registry.rb +62 -7
- data/lib/rubocop/cop/style/accessor_grouping.rb +147 -0
- data/lib/rubocop/cop/style/array_coercion.rb +63 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +3 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +146 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -4
- data/lib/rubocop/cop/style/case_like_if.rb +217 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +21 -0
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/copyright.rb +3 -3
- data/lib/rubocop/cop/style/date_time.rb +1 -1
- data/lib/rubocop/cop/style/dir.rb +2 -2
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
- data/lib/rubocop/cop/style/empty_literal.rb +5 -5
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +8 -10
- data/lib/rubocop/cop/style/float_division.rb +7 -10
- data/lib/rubocop/cop/style/format_string_token.rb +5 -5
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +62 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -11
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +1 -11
- data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
- data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
- data/lib/rubocop/cop/style/mutable_constant.rb +4 -4
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -5
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
- data/lib/rubocop/cop/style/next.rb +2 -2
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +3 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +4 -10
- data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +14 -10
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +122 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -2
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +4 -3
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +14 -23
- data/lib/rubocop/cop/style/redundant_self.rb +6 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -2
- data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +23 -2
- data/lib/rubocop/cop/style/symbol_array.rb +5 -5
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -2
- data/lib/rubocop/cop/team.rb +105 -81
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cop/utils/format_string.rb +19 -2
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/file_finder.rb +12 -12
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/name_similarity.rb +7 -3
- data/lib/rubocop/options.rb +15 -8
- data/lib/rubocop/path_util.rb +4 -19
- data/lib/rubocop/platform.rb +1 -1
- data/lib/rubocop/rake_task.rb +6 -9
- data/lib/rubocop/result_cache.rb +12 -8
- data/lib/rubocop/rspec/cop_helper.rb +4 -4
- data/lib/rubocop/rspec/expect_offense.rb +65 -21
- data/lib/rubocop/rspec/shared_contexts.rb +19 -16
- data/lib/rubocop/runner.rb +34 -33
- data/lib/rubocop/target_finder.rb +3 -3
- data/lib/rubocop/target_ruby.rb +2 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +34 -9
- data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
@@ -25,8 +25,9 @@ module RuboCop
|
|
25
25
|
# # good
|
26
26
|
# source 'https://rubygems.org' # strongly recommended
|
27
27
|
# source 'http://rubygems.org'
|
28
|
-
class InsecureProtocolSource <
|
28
|
+
class InsecureProtocolSource < Base
|
29
29
|
include RangeHelp
|
30
|
+
extend AutoCorrector
|
30
31
|
|
31
32
|
MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
|
32
33
|
'are insecure. ' \
|
@@ -35,34 +36,23 @@ module RuboCop
|
|
35
36
|
|
36
37
|
def_node_matcher :insecure_protocol_source?, <<~PATTERN
|
37
38
|
(send nil? :source
|
38
|
-
(sym ${:gemcutter :rubygems :rubyforge}))
|
39
|
+
$(sym ${:gemcutter :rubygems :rubyforge}))
|
39
40
|
PATTERN
|
40
41
|
|
41
42
|
def on_send(node)
|
42
|
-
insecure_protocol_source?(node) do |source|
|
43
|
+
insecure_protocol_source?(node) do |source_node, source|
|
43
44
|
message = format(MSG, source: source)
|
44
45
|
|
45
46
|
add_offense(
|
46
|
-
|
47
|
-
location: range(node.first_argument.loc.expression),
|
47
|
+
source_node,
|
48
48
|
message: message
|
49
|
-
)
|
49
|
+
) do |corrector|
|
50
|
+
corrector.replace(
|
51
|
+
source_node, "'https://rubygems.org'"
|
52
|
+
)
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|
52
|
-
|
53
|
-
def autocorrect(node)
|
54
|
-
lambda do |corrector|
|
55
|
-
corrector.replace(
|
56
|
-
node.first_argument, "'https://rubygems.org'"
|
57
|
-
)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def range(node)
|
64
|
-
range_between(node.begin_pos, node.end_pos)
|
65
|
-
end
|
66
56
|
end
|
67
57
|
end
|
68
58
|
end
|
@@ -7,6 +7,35 @@ module RuboCop
|
|
7
7
|
class Commissioner
|
8
8
|
include RuboCop::AST::Traversal
|
9
9
|
|
10
|
+
# How a Commissioner returns the results of the investigation
|
11
|
+
# as a list of Cop::InvestigationReport and any errors caught
|
12
|
+
# during the investigation.
|
13
|
+
# Immutable
|
14
|
+
# Consider creation API private
|
15
|
+
InvestigationReport = Struct.new(:processed_source, :cop_reports, :errors) do
|
16
|
+
def cops
|
17
|
+
@cops ||= cop_reports.map(&:cop)
|
18
|
+
end
|
19
|
+
|
20
|
+
def offenses_per_cop
|
21
|
+
@offenses_per_cop ||= cop_reports.map(&:offenses)
|
22
|
+
end
|
23
|
+
|
24
|
+
def correctors
|
25
|
+
@correctors ||= cop_reports.map(&:corrector)
|
26
|
+
end
|
27
|
+
|
28
|
+
def offenses
|
29
|
+
@offenses ||= offenses_per_cop.flatten(1)
|
30
|
+
end
|
31
|
+
|
32
|
+
def merge(investigation)
|
33
|
+
InvestigationReport.new(processed_source,
|
34
|
+
cop_reports + investigation.cop_reports,
|
35
|
+
errors + investigation.errors)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
10
39
|
attr_reader :errors
|
11
40
|
|
12
41
|
def initialize(cops, forces = [], options = {})
|
@@ -15,7 +44,7 @@ module RuboCop
|
|
15
44
|
@options = options
|
16
45
|
@callbacks = {}
|
17
46
|
|
18
|
-
|
47
|
+
reset
|
19
48
|
end
|
20
49
|
|
21
50
|
# Create methods like :on_send, :on_super, etc. They will be called
|
@@ -34,15 +63,21 @@ module RuboCop
|
|
34
63
|
end
|
35
64
|
end
|
36
65
|
|
66
|
+
# @return [InvestigationReport]
|
37
67
|
def investigate(processed_source)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
68
|
+
reset
|
69
|
+
|
70
|
+
@cops.each { |cop| cop.send :begin_investigation, processed_source }
|
71
|
+
if processed_source.valid_syntax?
|
72
|
+
invoke(:on_new_investigation, @cops)
|
73
|
+
invoke(:investigate, @forces, processed_source)
|
74
|
+
walk(processed_source.ast) unless @cops.empty?
|
75
|
+
invoke(:on_investigation_end, @cops)
|
76
|
+
else
|
77
|
+
invoke(:on_other_file, @cops)
|
78
|
+
end
|
79
|
+
reports = @cops.map { |cop| cop.send(:complete_investigation) }
|
80
|
+
InvestigationReport.new(processed_source, reports, @errors)
|
46
81
|
end
|
47
82
|
|
48
83
|
private
|
@@ -58,52 +93,15 @@ module RuboCop
|
|
58
93
|
end
|
59
94
|
end
|
60
95
|
|
61
|
-
def
|
96
|
+
def reset
|
62
97
|
@errors = []
|
98
|
+
@callbacks = {}
|
63
99
|
end
|
64
100
|
|
65
|
-
def
|
66
|
-
@callbacks.clear
|
67
|
-
end
|
68
|
-
|
69
|
-
# TODO: Bad design.
|
70
|
-
def prepare(processed_source)
|
71
|
-
@cops.each { |cop| cop.processed_source = processed_source }
|
72
|
-
end
|
73
|
-
|
74
|
-
# There are cops/forces that require their own custom processing.
|
75
|
-
# If they define the #investigate method, all input parameters passed
|
76
|
-
# to the commissioner will be passed to the cop too in order to do
|
77
|
-
# its own processing.
|
78
|
-
#
|
79
|
-
# These custom processors are invoked before the AST traversal,
|
80
|
-
# so they can build initial state that is later used by callbacks
|
81
|
-
# during the AST traversal.
|
82
|
-
def invoke_custom_processing(cops_or_forces, processed_source)
|
83
|
-
cops_or_forces.each do |cop|
|
84
|
-
next unless cop.respond_to?(:investigate)
|
85
|
-
|
86
|
-
with_cop_error_handling(cop) do
|
87
|
-
cop.investigate(processed_source)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# There are cops that require their own custom processing **after**
|
93
|
-
# the AST traversal. By performing the walk before invoking these
|
94
|
-
# custom processors, we allow these cops to build their own
|
95
|
-
# state during the primary AST traversal instead of performing their
|
96
|
-
# own AST traversals. Minimizing the number of walks is more efficient.
|
97
|
-
#
|
98
|
-
# If they define the #investigate_post_walk method, all input parameters
|
99
|
-
# passed to the commissioner will be passed to the cop too in order to do
|
100
|
-
# its own processing.
|
101
|
-
def invoke_custom_post_walk_processing(cops, processed_source)
|
101
|
+
def invoke(callback, cops, *args)
|
102
102
|
cops.each do |cop|
|
103
|
-
next unless cop.respond_to?(:investigate_post_walk)
|
104
|
-
|
105
103
|
with_cop_error_handling(cop) do
|
106
|
-
cop.
|
104
|
+
cop.send(callback, *args)
|
107
105
|
end
|
108
106
|
end
|
109
107
|
end
|
data/lib/rubocop/cop/cop.rb
CHANGED
@@ -1,36 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'uri'
|
4
|
+
require_relative 'legacy/corrections_proxy'
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
# A commissioner object is responsible for traversing the AST and invoking
|
14
|
-
# the specific callbacks on each cop.
|
15
|
-
# If a cop needs to do its own processing of the AST or depends on
|
16
|
-
# something else, it should define the `#investigate` method and do
|
17
|
-
# the processing there.
|
18
|
-
#
|
19
|
-
# @example
|
20
|
-
#
|
21
|
-
# class CustomCop < Cop
|
22
|
-
# def investigate(processed_source)
|
23
|
-
# # Do custom processing
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
class Cop
|
27
|
-
extend RuboCop::AST::Sexp
|
28
|
-
extend NodePattern::Macros
|
29
|
-
include RuboCop::AST::Sexp
|
30
|
-
include Util
|
31
|
-
include IgnoredNode
|
32
|
-
include AutocorrectLogic
|
8
|
+
# @deprecated Use Cop::Base instead
|
9
|
+
# Legacy scaffold for Cops.
|
10
|
+
# See https://docs.rubocop.org/rubocop/cop_api_v1_changelog.html
|
11
|
+
class Cop < Base
|
12
|
+
attr_reader :offenses
|
33
13
|
|
14
|
+
exclude_from_registry
|
15
|
+
|
16
|
+
# @deprecated
|
34
17
|
Correction = Struct.new(:lambda, :node, :cop) do
|
35
18
|
def call(corrector)
|
36
19
|
lambda.call(corrector)
|
@@ -41,100 +24,16 @@ module RuboCop
|
|
41
24
|
end
|
42
25
|
end
|
43
26
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
registry.without_department(:Test).cops
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.qualified_cop_name(name, origin)
|
58
|
-
registry.qualified_cop_name(name, origin)
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.inherited(subclass)
|
62
|
-
registry.enlist(subclass)
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.badge
|
66
|
-
@badge ||= Badge.for(name)
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.cop_name
|
70
|
-
badge.to_s
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.department
|
74
|
-
badge.department
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.lint?
|
78
|
-
department == :Lint
|
79
|
-
end
|
80
|
-
|
81
|
-
# Returns true if the cop name or the cop namespace matches any of the
|
82
|
-
# given names.
|
83
|
-
def self.match?(given_names)
|
84
|
-
return false unless given_names
|
85
|
-
|
86
|
-
given_names.include?(cop_name) ||
|
87
|
-
given_names.include?(department.to_s)
|
88
|
-
end
|
89
|
-
|
90
|
-
# List of cops that should not try to autocorrect at the same
|
91
|
-
# time as this cop
|
92
|
-
#
|
93
|
-
# @return [Array<RuboCop::Cop::Cop>]
|
94
|
-
#
|
95
|
-
# @api public
|
96
|
-
def self.autocorrect_incompatible_with
|
97
|
-
[]
|
98
|
-
end
|
99
|
-
|
100
|
-
def initialize(config = nil, options = nil)
|
101
|
-
@config = config || Config.new
|
102
|
-
@options = options || { debug: false }
|
103
|
-
|
104
|
-
@offenses = []
|
105
|
-
@corrections = []
|
106
|
-
@corrected_nodes = {}
|
107
|
-
@corrected_nodes.compare_by_identity
|
108
|
-
@processed_source = nil
|
109
|
-
end
|
110
|
-
|
111
|
-
def join_force?(_force_class)
|
112
|
-
false
|
113
|
-
end
|
114
|
-
|
115
|
-
def cop_config
|
116
|
-
# Use department configuration as basis, but let individual cop
|
117
|
-
# configuration override.
|
118
|
-
@cop_config ||= @config.for_cop(self.class.department.to_s)
|
119
|
-
.merge(@config.for_cop(self))
|
120
|
-
end
|
121
|
-
|
122
|
-
def message(_node = nil)
|
123
|
-
self.class::MSG
|
124
|
-
end
|
125
|
-
|
126
|
-
def add_offense(node, location: :expression, message: nil, severity: nil)
|
127
|
-
loc = find_location(node, location)
|
128
|
-
|
129
|
-
return if duplicate_location?(loc)
|
130
|
-
|
131
|
-
severity = find_severity(node, severity)
|
132
|
-
message = find_message(node, message)
|
133
|
-
|
134
|
-
status = enabled_line?(loc.line) ? correct(node) : :disabled
|
135
|
-
|
136
|
-
@offenses << Offense.new(severity, loc, message, name, status)
|
137
|
-
yield if block_given? && status != :disabled
|
27
|
+
def add_offense(node_or_range, location: :expression, message: nil, severity: nil, &block)
|
28
|
+
@v0_argument = node_or_range
|
29
|
+
range = find_location(node_or_range, location)
|
30
|
+
if block.nil? && !autocorrect?
|
31
|
+
super(range, message: message, severity: severity)
|
32
|
+
else
|
33
|
+
super(range, message: message, severity: severity) do |corrector|
|
34
|
+
emulate_v0_callsequence(corrector, &block)
|
35
|
+
end
|
36
|
+
end
|
138
37
|
end
|
139
38
|
|
140
39
|
def find_location(node, loc)
|
@@ -142,162 +41,119 @@ module RuboCop
|
|
142
41
|
loc.is_a?(Symbol) ? node.loc.public_send(loc) : loc
|
143
42
|
end
|
144
43
|
|
145
|
-
|
146
|
-
|
44
|
+
# @deprecated Use class method
|
45
|
+
def support_autocorrect?
|
46
|
+
# warn 'deprecated, use cop.class.support_autocorrect?' TODO
|
47
|
+
self.class.support_autocorrect?
|
147
48
|
end
|
148
49
|
|
149
|
-
def
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
@corrected_nodes[node] = true
|
50
|
+
def self.support_autocorrect?
|
51
|
+
method_defined?(:autocorrect)
|
52
|
+
end
|
154
53
|
|
155
|
-
|
156
|
-
|
54
|
+
def self.joining_forces
|
55
|
+
return unless method_defined?(:join_force?)
|
157
56
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
elsif disable_uncorrectable?
|
162
|
-
disable_uncorrectable(node)
|
163
|
-
:corrected_with_todo
|
164
|
-
else
|
165
|
-
:uncorrected
|
166
|
-
end
|
167
|
-
elsif disable_uncorrectable?
|
168
|
-
disable_uncorrectable(node)
|
169
|
-
:corrected_with_todo
|
57
|
+
cop = new
|
58
|
+
Force.all.select do |force_class|
|
59
|
+
cop.join_force?(force_class)
|
170
60
|
end
|
171
61
|
end
|
172
62
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
return
|
63
|
+
# @deprecated
|
64
|
+
def corrections
|
65
|
+
# warn 'Cop#corrections is deprecated' TODO
|
66
|
+
return [] unless @last_corrector
|
177
67
|
|
178
|
-
|
68
|
+
Legacy::CorrectionsProxy.new(@last_corrector)
|
179
69
|
end
|
180
70
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
line = node.location.line
|
186
|
-
return if @disabled_lines.key?(line)
|
187
|
-
|
188
|
-
@disabled_lines[line] = true
|
189
|
-
@corrections << Correction.new(disable_offense(node), node, self)
|
71
|
+
# Called before all on_... have been called
|
72
|
+
def on_new_investigation
|
73
|
+
investigate(processed_source) if respond_to?(:investigate)
|
74
|
+
super
|
190
75
|
end
|
191
76
|
|
192
|
-
|
193
|
-
|
194
|
-
|
77
|
+
# Called after all on_... have been called
|
78
|
+
def on_investigation_end
|
79
|
+
investigate_post_walk(processed_source) if respond_to?(:investigate_post_walk)
|
80
|
+
super
|
195
81
|
end
|
196
82
|
|
197
|
-
|
198
|
-
|
199
|
-
|
83
|
+
### Deprecated registry access
|
84
|
+
|
85
|
+
# @deprecated Use Registry.global
|
86
|
+
def self.registry
|
87
|
+
Registry.global
|
200
88
|
end
|
201
89
|
|
202
|
-
|
203
|
-
|
90
|
+
# @deprecated Use Registry.all
|
91
|
+
def self.all
|
92
|
+
Registry.all
|
204
93
|
end
|
205
94
|
|
206
|
-
|
207
|
-
|
95
|
+
# @deprecated Use Registry.qualified_cop_name
|
96
|
+
def self.qualified_cop_name(name, origin)
|
97
|
+
Registry.qualified_cop_name(name, origin)
|
208
98
|
end
|
209
99
|
|
100
|
+
# @deprecated
|
101
|
+
# Open issue if there's a valid use case to include this in Base
|
210
102
|
def parse(source, path = nil)
|
211
103
|
ProcessedSource.new(source, target_ruby_version, path)
|
212
104
|
end
|
213
105
|
|
214
|
-
|
215
|
-
@cop_name ||= self.class.cop_name
|
216
|
-
end
|
217
|
-
|
218
|
-
alias name cop_name
|
219
|
-
|
220
|
-
def relevant_file?(file)
|
221
|
-
file == RuboCop::AST::ProcessedSource::STRING_SOURCE_NAME ||
|
222
|
-
file_name_matches_any?(file, 'Include', true) &&
|
223
|
-
!file_name_matches_any?(file, 'Exclude', false)
|
224
|
-
end
|
225
|
-
|
226
|
-
def excluded_file?(file)
|
227
|
-
!relevant_file?(file)
|
228
|
-
end
|
106
|
+
private
|
229
107
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# (2) the cop's source code
|
235
|
-
# (3) the config (eg a .rubocop.yml file)
|
236
|
-
#
|
237
|
-
# For example, some cops may want to look at other parts of
|
238
|
-
# the codebase being inspected to find violations. A cop may
|
239
|
-
# use the presence or absence of file `foo.rb` to determine
|
240
|
-
# whether a certain violation exists in `bar.rb`.
|
241
|
-
#
|
242
|
-
# Overriding this method allows the cop to indicate to RuboCop's
|
243
|
-
# ResultCache system when those external dependencies change,
|
244
|
-
# ie when the ResultCache should be invalidated.
|
245
|
-
def external_dependency_checksum
|
246
|
-
nil
|
108
|
+
def begin_investigation(processed_source)
|
109
|
+
super
|
110
|
+
@offenses = @current_offenses
|
111
|
+
@last_corrector = @current_corrector
|
247
112
|
end
|
248
113
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
annotate(message || message(node))
|
114
|
+
# Override Base
|
115
|
+
def callback_argument(_range)
|
116
|
+
@v0_argument
|
253
117
|
end
|
254
118
|
|
255
|
-
def
|
256
|
-
|
257
|
-
config, cop_name, cop_config, @options
|
258
|
-
).annotate(message)
|
119
|
+
def apply_correction(corrector)
|
120
|
+
suppress_clobbering { super }
|
259
121
|
end
|
260
122
|
|
261
|
-
|
262
|
-
|
263
|
-
|
123
|
+
# Just for legacy
|
124
|
+
def emulate_v0_callsequence(corrector)
|
125
|
+
lambda = correction_lambda
|
126
|
+
yield corrector if block_given?
|
127
|
+
unless corrector.empty?
|
128
|
+
raise 'Your cop must inherit from Cop::Base and extend AutoCorrector'
|
129
|
+
end
|
264
130
|
|
265
|
-
|
266
|
-
patterns.any? do |pattern|
|
267
|
-
# Try to match the absolute path, as Exclude properties are absolute.
|
268
|
-
next true if match_path?(pattern, file)
|
131
|
+
return unless lambda
|
269
132
|
|
270
|
-
|
271
|
-
|
272
|
-
match_path?(pattern, path)
|
133
|
+
suppress_clobbering do
|
134
|
+
lambda.call(corrector)
|
273
135
|
end
|
274
136
|
end
|
275
137
|
|
276
|
-
def
|
277
|
-
return
|
278
|
-
|
279
|
-
@processed_source.comment_config.cop_enabled_at_line?(self, line_number)
|
280
|
-
end
|
138
|
+
def correction_lambda
|
139
|
+
return unless correction_strategy == :attempt_correction && support_autocorrect?
|
281
140
|
|
282
|
-
|
283
|
-
|
141
|
+
dedup_on_node(@v0_argument) do
|
142
|
+
autocorrect(@v0_argument)
|
143
|
+
end
|
284
144
|
end
|
285
145
|
|
286
|
-
def
|
287
|
-
|
146
|
+
def dedup_on_node(node)
|
147
|
+
@corrected_nodes ||= {}.compare_by_identity
|
148
|
+
yield unless @corrected_nodes.key?(node)
|
149
|
+
ensure
|
150
|
+
@corrected_nodes[node] = true
|
288
151
|
end
|
289
152
|
|
290
|
-
def
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
if Severity::NAMES.include?(severity.to_sym)
|
295
|
-
severity.to_sym
|
296
|
-
else
|
297
|
-
message = "Warning: Invalid severity '#{severity}'. " \
|
298
|
-
"Valid severities are #{Severity::NAMES.join(', ')}."
|
299
|
-
warn(Rainbow(message).red)
|
300
|
-
end
|
153
|
+
def suppress_clobbering
|
154
|
+
yield
|
155
|
+
rescue ::Parser::ClobberingError
|
156
|
+
# ignore Clobbering errors
|
301
157
|
end
|
302
158
|
end
|
303
159
|
end
|