rubocop 0.58.2 → 0.59.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 +1 -1
- data/config/default.yml +22 -7
- data/config/disabled.yml +33 -4
- data/config/enabled.yml +4 -11
- data/lib/rubocop.rb +5 -0
- data/lib/rubocop/ast/builder.rb +1 -0
- data/lib/rubocop/ast/node.rb +11 -33
- data/lib/rubocop/ast/node/block_node.rb +8 -1
- data/lib/rubocop/ast/node/defined_node.rb +13 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +16 -5
- data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +21 -0
- data/lib/rubocop/ast/node/send_node.rb +3 -12
- data/lib/rubocop/ast/traversal.rb +10 -0
- data/lib/rubocop/cli.rb +4 -1
- data/lib/rubocop/config.rb +21 -5
- data/lib/rubocop/config_loader.rb +2 -0
- data/lib/rubocop/config_loader_resolver.rb +3 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +64 -0
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -0
- data/lib/rubocop/cop/commissioner.rb +2 -0
- data/lib/rubocop/cop/cop.rb +3 -0
- data/lib/rubocop/cop/corrector.rb +2 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -0
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
- data/lib/rubocop/cop/correctors/space_corrector.rb +2 -0
- data/lib/rubocop/cop/force.rb +1 -0
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
- data/lib/rubocop/cop/generator.rb +1 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +4 -0
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +5 -4
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +35 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -0
- data/lib/rubocop/cop/layout/indent_array.rb +1 -0
- data/lib/rubocop/cop/layout/indent_heredoc.rb +3 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +34 -11
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -0
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_comment.rb +1 -0
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +16 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -0
- data/lib/rubocop/cop/layout/tab.rb +1 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -0
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +9 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +2 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +3 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -0
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -0
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
- data/lib/rubocop/cop/lint/script_permission.rb +1 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -0
- data/lib/rubocop/cop/lint/unneeded_cop_disable_directive.rb +1 -0
- data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +1 -0
- data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +2 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +3 -0
- data/lib/rubocop/cop/lint/void.rb +1 -0
- data/lib/rubocop/cop/message_annotator.rb +1 -0
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -0
- data/lib/rubocop/cop/metrics/line_length.rb +6 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -0
- data/lib/rubocop/cop/mixin/classish_length.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -6
- data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
- data/lib/rubocop/cop/mixin/ignored_methods.rb +19 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +25 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +5 -3
- data/lib/rubocop/cop/mixin/percent_literal.rb +2 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +2 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +2 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +6 -1
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +4 -0
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -0
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +2 -0
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
- data/lib/rubocop/cop/naming/file_name.rb +4 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -0
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
- data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +1 -0
- data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +1 -0
- data/lib/rubocop/cop/naming/variable_name.rb +1 -0
- data/lib/rubocop/cop/performance/case_when_splat.rb +11 -7
- data/lib/rubocop/cop/performance/casecmp.rb +33 -42
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +77 -0
- data/lib/rubocop/cop/performance/compare_with_block.rb +3 -0
- data/lib/rubocop/cop/performance/regexp_match.rb +1 -0
- data/lib/rubocop/cop/performance/sample.rb +2 -0
- data/lib/rubocop/cop/performance/size.rb +8 -2
- data/lib/rubocop/cop/performance/string_replacement.rb +1 -0
- data/lib/rubocop/cop/rails/active_support_aliases.rb +1 -0
- data/lib/rubocop/cop/rails/bulk_change_table.rb +9 -2
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -0
- data/lib/rubocop/cop/rails/delegate.rb +7 -2
- data/lib/rubocop/cop/rails/dynamic_find_by.rb +1 -0
- data/lib/rubocop/cop/rails/find_each.rb +7 -2
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
- data/lib/rubocop/cop/rails/http_status.rb +2 -0
- data/lib/rubocop/cop/rails/inverse_of.rb +4 -0
- data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +1 -0
- data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +1 -0
- data/lib/rubocop/cop/rails/save_bang.rb +189 -38
- data/lib/rubocop/cop/rails/time_zone.rb +1 -0
- data/lib/rubocop/cop/security/eval.rb +1 -0
- data/lib/rubocop/cop/security/json_load.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +6 -3
- data/lib/rubocop/cop/severity.rb +1 -0
- data/lib/rubocop/cop/style/and_or.rb +3 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -4
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +3 -0
- data/lib/rubocop/cop/style/class_vars.rb +1 -1
- data/lib/rubocop/cop/style/colon_method_definition.rb +1 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
- data/lib/rubocop/cop/style/copyright.rb +7 -2
- data/lib/rubocop/cop/style/date_time.rb +40 -7
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +8 -0
- data/lib/rubocop/cop/style/empty_else.rb +2 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -0
- data/lib/rubocop/cop/style/for.rb +56 -10
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -0
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -5
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -5
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/missing_else.rb +1 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +65 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +1 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +45 -5
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/or_assignment.rb +2 -0
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +1 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +13 -0
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -1
- data/lib/rubocop/cop/style/redundant_return.rb +1 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -0
- data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -0
- data/lib/rubocop/cop/style/semicolon.rb +4 -0
- data/lib/rubocop/cop/style/signal_exception.rb +1 -0
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -8
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -0
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
- data/lib/rubocop/cop/style/unneeded_condition.rb +13 -2
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +2 -0
- data/lib/rubocop/cop/style/word_array.rb +13 -1
- data/lib/rubocop/cop/team.rb +1 -0
- data/lib/rubocop/cop/variable_force.rb +5 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +4 -0
- data/lib/rubocop/cop/variable_force/branch.rb +4 -0
- data/lib/rubocop/cop/variable_force/branchable.rb +2 -0
- data/lib/rubocop/cop/variable_force/scope.rb +6 -0
- data/lib/rubocop/cop/variable_force/variable_table.rb +1 -0
- data/lib/rubocop/file_finder.rb +2 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -4
- data/lib/rubocop/formatter/file_list_formatter.rb +1 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -0
- data/lib/rubocop/options.rb +16 -0
- data/lib/rubocop/path_util.rb +16 -1
- data/lib/rubocop/processed_source.rb +4 -0
- data/lib/rubocop/remote_config.rb +6 -1
- data/lib/rubocop/result_cache.rb +1 -0
- data/lib/rubocop/rspec/cop_helper.rb +3 -5
- data/lib/rubocop/rspec/shared_examples.rb +1 -9
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/target_finder.rb +2 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +7 -2
@@ -4,11 +4,12 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Security
|
6
6
|
# This cop checks for the use of `Kernel#open`.
|
7
|
+
#
|
7
8
|
# `Kernel#open` enables not only file access but also process invocation
|
8
|
-
# by prefixing a pipe symbol (e.g., `open("| ls")`).
|
9
|
+
# by prefixing a pipe symbol (e.g., `open("| ls")`). So, it may lead to
|
9
10
|
# a serious security risk by using variable input to the argument of
|
10
|
-
# `Kernel#open`.
|
11
|
-
# explicitly.
|
11
|
+
# `Kernel#open`. It would be better to use `File.open`, `IO.popen` or
|
12
|
+
# `URI#open` explicitly.
|
12
13
|
#
|
13
14
|
# @example
|
14
15
|
# # bad
|
@@ -17,6 +18,7 @@ module RuboCop
|
|
17
18
|
# # good
|
18
19
|
# File.open(something)
|
19
20
|
# IO.popen(something)
|
21
|
+
# URI.parse(something).open
|
20
22
|
class Open < Cop
|
21
23
|
MSG = 'The use of `Kernel#open` is a serious security risk.'.freeze
|
22
24
|
|
@@ -39,6 +41,7 @@ module RuboCop
|
|
39
41
|
def on_send(node)
|
40
42
|
open?(node) do |code|
|
41
43
|
return if safe?(code)
|
44
|
+
|
42
45
|
add_offense(node, location: :selector)
|
43
46
|
end
|
44
47
|
end
|
data/lib/rubocop/cop/severity.rb
CHANGED
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# This cop checks for uses of `and` and `or`, and suggests using `&&` and
|
7
|
-
#
|
7
|
+
# `||` instead. It can be configured to check only in conditions, or in
|
8
8
|
# all contexts.
|
9
9
|
#
|
10
10
|
# @example EnforcedStyle: always (default)
|
@@ -110,11 +110,11 @@ module RuboCop
|
|
110
110
|
# recurse down a level and add parens to 'obj.method arg'
|
111
111
|
# however, 'not x' also parses as (send x :!)
|
112
112
|
def correct_not(node, receiver, corrector)
|
113
|
-
if node.
|
113
|
+
if node.prefix_bang?
|
114
114
|
return unless receiver.send_type?
|
115
115
|
|
116
116
|
correct_send(receiver, corrector)
|
117
|
-
elsif node.
|
117
|
+
elsif node.prefix_not?
|
118
118
|
correct_other(node, corrector)
|
119
119
|
else
|
120
120
|
raise 'unrecognized unary negation operator'
|
@@ -73,6 +73,7 @@ module RuboCop
|
|
73
73
|
#
|
74
74
|
class BlockDelimiters < Cop
|
75
75
|
include ConfigurableEnforcedStyle
|
76
|
+
include IgnoredMethods
|
76
77
|
|
77
78
|
def on_send(node)
|
78
79
|
return unless node.arguments?
|
@@ -189,6 +190,7 @@ module RuboCop
|
|
189
190
|
# In that case, one of the K/V pairs could contain a block node
|
190
191
|
# which could change in meaning if do...end replaced {...}
|
191
192
|
return if node.braces?
|
193
|
+
|
192
194
|
node.each_child_node { |child| get_blocks(child, &block) }
|
193
195
|
when :pair
|
194
196
|
node.each_child_node { |child| get_blocks(child, &block) }
|
@@ -240,10 +242,6 @@ module RuboCop
|
|
240
242
|
node.send_node.arguments? && !node.send_node.parenthesized?
|
241
243
|
end
|
242
244
|
|
243
|
-
def ignored_method?(method_name)
|
244
|
-
cop_config['IgnoredMethods'].map(&:to_sym).include?(method_name)
|
245
|
-
end
|
246
|
-
|
247
245
|
def functional_method?(method_name)
|
248
246
|
cop_config['FunctionalMethods'].map(&:to_sym).include?(method_name)
|
249
247
|
end
|
@@ -127,13 +127,12 @@ module RuboCop
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def remove_braces_with_whitespace(corrector, node, space)
|
130
|
-
right_brace_and_space = right_brace_and_space(node.loc.end, space)
|
131
|
-
|
132
130
|
if node.multiline?
|
133
131
|
remove_braces_with_range(corrector,
|
134
132
|
left_whole_line_range(node.loc.begin),
|
135
133
|
right_whole_line_range(node.loc.end))
|
136
134
|
else
|
135
|
+
right_brace_and_space = right_brace_and_space(node.loc.end, space)
|
137
136
|
left_brace_and_space = left_brace_and_space(node.loc.begin, space)
|
138
137
|
remove_braces_with_range(corrector,
|
139
138
|
left_brace_and_space,
|
@@ -155,7 +154,7 @@ module RuboCop
|
|
155
154
|
end
|
156
155
|
|
157
156
|
def right_whole_line_range(loc_end)
|
158
|
-
if range_by_whole_lines(loc_end).source.strip
|
157
|
+
if range_by_whole_lines(loc_end).source.strip =~ /}\s*,?\z/
|
159
158
|
range_by_whole_lines(loc_end, include_final_newline: true)
|
160
159
|
else
|
161
160
|
loc_end
|
@@ -33,6 +33,7 @@ module RuboCop
|
|
33
33
|
def on_class(node)
|
34
34
|
_name, superclass, body = *node
|
35
35
|
return if superclass && style != :nested
|
36
|
+
|
36
37
|
check_style(node, body)
|
37
38
|
end
|
38
39
|
|
@@ -129,11 +130,13 @@ module RuboCop
|
|
129
130
|
|
130
131
|
def check_nested_style(node)
|
131
132
|
return unless compact_node_name?(node)
|
133
|
+
|
132
134
|
add_offense(node, location: :name, message: NESTED_MSG)
|
133
135
|
end
|
134
136
|
|
135
137
|
def check_compact_style(node, body)
|
136
138
|
return unless one_child?(body) && !compact_node_name?(node)
|
139
|
+
|
137
140
|
add_offense(node, location: :name, message: COMPACT_MSG)
|
138
141
|
end
|
139
142
|
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
line = processed_source.lines[line_position - 1]
|
48
48
|
next if heredoc_lines.any? { |r| r.include?(line_position) }
|
49
49
|
next unless offensive?(line)
|
50
|
+
|
50
51
|
range = source_range(processed_source.buffer,
|
51
52
|
line_position,
|
52
53
|
(location.column)...(location.last_column))
|
@@ -74,6 +75,7 @@ module RuboCop
|
|
74
75
|
|
75
76
|
def extract_heredoc_lines(ast)
|
76
77
|
return [] unless ast
|
78
|
+
|
77
79
|
ast.each_node(:str, :dstr, :xstr).select(&:heredoc?).map do |node|
|
78
80
|
body = node.location.heredoc_body
|
79
81
|
(body.first_line...body.last_line)
|
@@ -69,6 +69,7 @@ module RuboCop
|
|
69
69
|
|
70
70
|
def expand_elsif(node, elsif_branches = [])
|
71
71
|
return [] if node.nil? || !node.if_type?
|
72
|
+
|
72
73
|
_condition, elsif_branch, else_branch = *node
|
73
74
|
elsif_branches << elsif_branch
|
74
75
|
if else_branch && else_branch.if_type?
|
@@ -100,6 +101,7 @@ module RuboCop
|
|
100
101
|
def assignment_rhs_exist?(node)
|
101
102
|
parent = node.parent
|
102
103
|
return true unless parent
|
104
|
+
|
103
105
|
!(parent.mlhs_type? || parent.resbody_type?)
|
104
106
|
end
|
105
107
|
end
|
@@ -6,12 +6,12 @@ module RuboCop
|
|
6
6
|
# Check that a copyright notice was given in each source file.
|
7
7
|
#
|
8
8
|
# The default regexp for an acceptable copyright notice can be found in
|
9
|
-
# config/default.yml.
|
9
|
+
# config/default.yml. The default can be changed as follows:
|
10
10
|
#
|
11
11
|
# Style/Copyright:
|
12
12
|
# Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc'
|
13
13
|
#
|
14
|
-
# This regex string is treated as an unanchored regex.
|
14
|
+
# This regex string is treated as an unanchored regex. For each file
|
15
15
|
# that RuboCop scans, a comment that matches this regex must be found or
|
16
16
|
# an offense is reported.
|
17
17
|
#
|
@@ -26,6 +26,7 @@ module RuboCop
|
|
26
26
|
def investigate(processed_source)
|
27
27
|
return if notice.empty?
|
28
28
|
return if notice_found?(processed_source)
|
29
|
+
|
29
30
|
range = source_range(processed_source.buffer, 1, 0)
|
30
31
|
add_offense(insert_notice_before(processed_source),
|
31
32
|
location: range, message: format(MSG, notice: notice))
|
@@ -33,6 +34,7 @@ module RuboCop
|
|
33
34
|
|
34
35
|
def autocorrect(token)
|
35
36
|
raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
|
37
|
+
|
36
38
|
regex = Regexp.new(notice)
|
37
39
|
unless autocorrect_notice =~ regex
|
38
40
|
raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
|
@@ -64,12 +66,14 @@ module RuboCop
|
|
64
66
|
|
65
67
|
def shebang_token?(processed_source, token_index)
|
66
68
|
return false if token_index >= processed_source.tokens.size
|
69
|
+
|
67
70
|
token = processed_source.tokens[token_index]
|
68
71
|
token.comment? && token.text =~ /^#!.*$/
|
69
72
|
end
|
70
73
|
|
71
74
|
def encoding_token?(processed_source, token_index)
|
72
75
|
return false if token_index >= processed_source.tokens.size
|
76
|
+
|
73
77
|
token = processed_source.tokens[token_index]
|
74
78
|
token.comment? && token.text =~ /^#.*coding\s?[:=]\s?(?:UTF|utf)-8/
|
75
79
|
end
|
@@ -79,6 +83,7 @@ module RuboCop
|
|
79
83
|
notice_regexp = Regexp.new(notice)
|
80
84
|
processed_source.each_token do |token|
|
81
85
|
break unless token.comment?
|
86
|
+
|
82
87
|
notice_found = !(token.text =~ notice_regexp).nil?
|
83
88
|
break if notice_found
|
84
89
|
end
|
@@ -3,8 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop checks for
|
7
|
-
# `
|
6
|
+
# This cop checks for consistent usage of the `DateTime` class over the
|
7
|
+
# `Time` class. This cop is disabled by default since these classes,
|
8
|
+
# although highly overlapping, have particularities that make them not
|
9
|
+
# replaceable in certain situations when dealing with multiple timezones
|
10
|
+
# and/or DST.
|
8
11
|
#
|
9
12
|
# @example
|
10
13
|
#
|
@@ -17,13 +20,30 @@ module RuboCop
|
|
17
20
|
# # bad - uses `DateTime` for modern date
|
18
21
|
# DateTime.iso8601('2016-06-29')
|
19
22
|
#
|
20
|
-
# # good - uses `
|
21
|
-
#
|
23
|
+
# # good - uses `Time` for modern date
|
24
|
+
# Time.iso8601('2016-06-29')
|
22
25
|
#
|
23
26
|
# # good - uses `DateTime` with start argument for historical date
|
24
27
|
# DateTime.iso8601('1751-04-23', Date::ENGLAND)
|
28
|
+
#
|
29
|
+
# @example AllowCoercion: false (default)
|
30
|
+
#
|
31
|
+
# # bad - coerces to `DateTime`
|
32
|
+
# something.to_datetime
|
33
|
+
#
|
34
|
+
# # good - coerces to `Time`
|
35
|
+
# something.to_time
|
36
|
+
#
|
37
|
+
# @example AllowCoercion: true
|
38
|
+
#
|
39
|
+
# # good
|
40
|
+
# something.to_datetime
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# something.to_time
|
25
44
|
class DateTime < Cop
|
26
|
-
|
45
|
+
CLASS_MSG = 'Prefer Time over DateTime.'.freeze
|
46
|
+
COERCION_MSG = 'Do not use #to_datetime.'.freeze
|
27
47
|
|
28
48
|
def_node_matcher :date_time?, <<-PATTERN
|
29
49
|
(send (const {nil? (cbase)} :DateTime) ...)
|
@@ -33,10 +53,23 @@ module RuboCop
|
|
33
53
|
(send _ _ _ (const (const nil? :Date) _))
|
34
54
|
PATTERN
|
35
55
|
|
56
|
+
def_node_matcher :to_datetime?, <<-PATTERN
|
57
|
+
(send _ :to_datetime)
|
58
|
+
PATTERN
|
59
|
+
|
36
60
|
def on_send(node)
|
37
|
-
return unless date_time?(node)
|
61
|
+
return unless date_time?(node) ||
|
62
|
+
(to_datetime?(node) && disallow_coercion?)
|
38
63
|
return if historic_date?(node)
|
39
|
-
|
64
|
+
|
65
|
+
message = to_datetime?(node) ? COERCION_MSG : CLASS_MSG
|
66
|
+
add_offense(node, message: message)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def disallow_coercion?
|
72
|
+
!cop_config['AllowCoercion']
|
40
73
|
end
|
41
74
|
end
|
42
75
|
end
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
def_node_matcher :double_negative?, '(send (send _ :!) :!)'
|
26
26
|
|
27
27
|
def on_send(node)
|
28
|
-
return unless double_negative?(node) && node.
|
28
|
+
return unless double_negative?(node) && node.prefix_bang?
|
29
29
|
|
30
30
|
add_offense(node, location: :selector)
|
31
31
|
end
|
@@ -43,6 +43,14 @@ module RuboCop
|
|
43
43
|
|
44
44
|
def on_case(case_node)
|
45
45
|
return if case_node.condition
|
46
|
+
return if case_node.when_branches.any? do |when_branch|
|
47
|
+
when_branch.each_descendant.any?(&:return_type?)
|
48
|
+
end
|
49
|
+
|
50
|
+
if (else_branch = case_node.else_branch)
|
51
|
+
return if else_branch.return_type? ||
|
52
|
+
else_branch.each_descendant.any?(&:return_type?)
|
53
|
+
end
|
46
54
|
|
47
55
|
add_offense(case_node, location: :keyword)
|
48
56
|
end
|
@@ -148,12 +148,14 @@ module RuboCop
|
|
148
148
|
|
149
149
|
def else_line_range(loc)
|
150
150
|
return 0..0 if loc.else.nil? || loc.end.nil?
|
151
|
+
|
151
152
|
loc.else.first_line..loc.end.first_line
|
152
153
|
end
|
153
154
|
|
154
155
|
def base_node(node)
|
155
156
|
return node if node.case_type?
|
156
157
|
return node unless node.elsif?
|
158
|
+
|
157
159
|
node.each_ancestor(:if, :case, :when).find(-> { node }) do |parent|
|
158
160
|
parent.loc.end
|
159
161
|
end
|
@@ -124,6 +124,7 @@ module RuboCop
|
|
124
124
|
|
125
125
|
def add_offense_for_same_line(node, line_node)
|
126
126
|
return if special_line_keyword?(line_node)
|
127
|
+
|
127
128
|
add_offense(
|
128
129
|
node,
|
129
130
|
location: line_node.loc.expression,
|
@@ -134,6 +135,7 @@ module RuboCop
|
|
134
135
|
def add_offense_for_different_line(node, line_node, line_diff)
|
135
136
|
sign = line_diff > 0 ? :+ : :-
|
136
137
|
return if line_with_offset?(line_node, sign, line_diff.abs)
|
138
|
+
|
137
139
|
add_offense(
|
138
140
|
node,
|
139
141
|
location: line_node.loc.expression,
|
@@ -43,12 +43,24 @@ module RuboCop
|
|
43
43
|
include RangeHelp
|
44
44
|
|
45
45
|
EACH_LENGTH = 'each'.length
|
46
|
+
PREFER_EACH = 'Prefer `each` over `for`.'.freeze
|
47
|
+
PREFER_FOR = 'Prefer `for` over `each`.'.freeze
|
48
|
+
|
49
|
+
def_node_matcher :deconstruct_for, <<-PATTERN
|
50
|
+
(for $_item $_enumerable _block)
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
def_node_matcher :deconstruct_each, <<-PATTERN
|
54
|
+
(block (send $_enumerable :each) $_ _block)
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def_node_matcher :extract_variables, <<-PATTERN
|
58
|
+
(args $_)
|
59
|
+
PATTERN
|
46
60
|
|
47
61
|
def on_for(node)
|
48
62
|
if style == :each
|
49
|
-
|
50
|
-
|
51
|
-
add_offense(node, location: :keyword, message: msg) do
|
63
|
+
add_offense(node, message: PREFER_EACH) do
|
52
64
|
opposite_style_detected
|
53
65
|
end
|
54
66
|
else
|
@@ -63,23 +75,57 @@ module RuboCop
|
|
63
75
|
!node.send_node.arguments?
|
64
76
|
|
65
77
|
if style == :for
|
66
|
-
incorrect_style_detected(node
|
78
|
+
incorrect_style_detected(node)
|
67
79
|
else
|
68
80
|
correct_style_detected
|
69
81
|
end
|
70
82
|
end
|
71
83
|
|
72
|
-
|
84
|
+
def autocorrect(node)
|
85
|
+
if style == :each
|
86
|
+
autocorrect_to_each(node)
|
87
|
+
else
|
88
|
+
autocorrect_to_for(node)
|
89
|
+
end
|
90
|
+
end
|
73
91
|
|
74
|
-
|
75
|
-
end_pos = method.source_range.end_pos
|
76
|
-
range = range_between(end_pos - EACH_LENGTH, end_pos)
|
77
|
-
msg = 'Prefer `for` over `each`.'
|
92
|
+
private
|
78
93
|
|
79
|
-
|
94
|
+
def incorrect_style_detected(node)
|
95
|
+
add_offense(node, message: PREFER_FOR) do
|
80
96
|
opposite_style_detected
|
81
97
|
end
|
82
98
|
end
|
99
|
+
|
100
|
+
def autocorrect_to_each(node)
|
101
|
+
item, enumerable = deconstruct_for(node)
|
102
|
+
replacement_range = replacement_range(node, node.loc.begin.end_pos)
|
103
|
+
correction = "#{enumerable.source}.each do |#{item.source}|"
|
104
|
+
|
105
|
+
->(corrector) { corrector.replace(replacement_range, correction) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def autocorrect_to_for(node)
|
109
|
+
enumerable, items = deconstruct_each(node)
|
110
|
+
variables = extract_variables(items)
|
111
|
+
|
112
|
+
if variables.nil?
|
113
|
+
replacement_range = replacement_range(node, node.loc.begin.end_pos)
|
114
|
+
correction = "for _ in #{enumerable.source} do"
|
115
|
+
else
|
116
|
+
replacement_range = replacement_range(node,
|
117
|
+
items.loc.expression.end_pos)
|
118
|
+
correction = "for #{variables.source} in #{enumerable.source} do"
|
119
|
+
end
|
120
|
+
|
121
|
+
->(corrector) { corrector.replace(replacement_range, correction) }
|
122
|
+
end
|
123
|
+
|
124
|
+
def replacement_range(node, end_pos)
|
125
|
+
Parser::Source::Range.new(node.loc.expression.source_buffer,
|
126
|
+
node.loc.expression.begin_pos,
|
127
|
+
end_pos)
|
128
|
+
end
|
83
129
|
end
|
84
130
|
end
|
85
131
|
end
|