rubocop 0.24.1 → 0.25.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/.rubocop_todo.yml +12 -8
- data/.travis.yml +1 -1
- data/CHANGELOG.md +42 -0
- data/Gemfile +2 -0
- data/README.md +27 -6
- data/bin/rubocop +10 -15
- data/config/default.yml +72 -25
- data/config/enabled.yml +57 -25
- data/lib/rubocop.rb +15 -8
- data/lib/rubocop/config_loader.rb +11 -7
- data/lib/rubocop/cop/cop.rb +16 -16
- data/lib/rubocop/cop/ignored_node.rb +11 -4
- data/lib/rubocop/cop/lint/block_alignment.rb +29 -4
- data/lib/rubocop/cop/lint/debugger.rb +8 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +5 -1
- data/lib/rubocop/cop/lint/end_alignment.rb +5 -5
- data/lib/rubocop/cop/lint/end_in_method.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
- data/lib/rubocop/cop/{style → metrics}/block_nesting.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/class_length.rb +4 -4
- data/lib/rubocop/cop/{style → metrics}/cyclomatic_complexity.rb +5 -16
- data/lib/rubocop/cop/{style → metrics}/line_length.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/method_length.rb +8 -4
- data/lib/rubocop/cop/{style → metrics}/parameter_lists.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +61 -0
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +10 -2
- data/lib/rubocop/cop/mixin/code_length.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_naming.rb +6 -20
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/if_node.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +32 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
- data/lib/rubocop/cop/mixin/{check_methods.rb → on_method.rb} +3 -3
- data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +24 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +2 -1
- data/lib/rubocop/cop/mixin/space_inside.rb +33 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +14 -14
- data/lib/rubocop/cop/mixin/string_help.rb +4 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +1 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/rails/output.rb +4 -2
- data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
- data/lib/rubocop/cop/style/align_hash.rb +9 -1
- data/lib/rubocop/cop/style/and_or.rb +37 -3
- data/lib/rubocop/cop/style/bare_percent_literals.rb +46 -0
- data/lib/rubocop/cop/style/block_end_newline.rb +56 -0
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +31 -3
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +6 -2
- data/lib/rubocop/cop/style/end_of_line.rb +3 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -6
- data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -7
- data/lib/rubocop/cop/style/indentation_width.rb +3 -8
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/method_name.rb +4 -18
- data/lib/rubocop/cop/style/multiline_block_layout.rb +73 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_while.rb +2 -2
- data/lib/rubocop/cop/style/next.rb +12 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +6 -6
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +22 -8
- data/lib/rubocop/cop/style/percent_q_literals.rb +53 -0
- data/lib/rubocop/cop/style/predicate_name.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -2
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +7 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +2 -2
- data/lib/rubocop/cop/style/space_after_method_name.rb +2 -2
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +14 -10
- data/lib/rubocop/cop/style/space_inside_brackets.rb +5 -1
- data/lib/rubocop/cop/style/string_literals.rb +5 -8
- data/lib/rubocop/cop/style/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +2 -4
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -0
- data/lib/rubocop/cop/style/variable_interpolation.rb +14 -2
- data/lib/rubocop/cop/style/variable_name.rb +17 -17
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -5
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force.rb +7 -6
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/processed_source.rb +5 -22
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.25.0.md +91 -0
- data/rubocop.gemspec +2 -3
- data/spec/project_spec.rb +1 -1
- data/spec/rubocop/cli_spec.rb +70 -44
- data/spec/rubocop/comment_config_spec.rb +6 -6
- data/spec/rubocop/config_loader_spec.rb +19 -13
- data/spec/rubocop/config_spec.rb +3 -3
- data/spec/rubocop/cop/commissioner_spec.rb +1 -1
- data/spec/rubocop/cop/cop_spec.rb +3 -3
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +113 -6
- data/spec/rubocop/cop/lint/debugger_spec.rb +10 -6
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +12 -0
- data/spec/rubocop/cop/{style → metrics}/block_nesting_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/class_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/cyclomatic_complexity_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/if_unless_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/{style → metrics}/line_length_spec.rb +7 -7
- data/spec/rubocop/cop/{style → metrics}/method_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/parameter_lists_spec.rb +1 -1
- data/spec/rubocop/cop/metrics/perceived_complexity_spec.rb +222 -0
- data/spec/rubocop/cop/{style → metrics}/while_until_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/rails/output_spec.rb +8 -2
- data/spec/rubocop/cop/style/align_hash_spec.rb +7 -0
- data/spec/rubocop/cop/style/and_or_spec.rb +245 -43
- data/spec/rubocop/cop/style/bare_percent_literals_spec.rb +132 -0
- data/spec/rubocop/cop/style/block_end_newline_spec.rb +61 -0
- data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +34 -0
- data/spec/rubocop/cop/style/end_of_line_spec.rb +8 -0
- data/spec/rubocop/cop/style/guard_clause_spec.rb +1 -1
- data/spec/rubocop/cop/style/multiline_block_layout_spec.rb +138 -0
- data/spec/rubocop/cop/style/next_spec.rb +32 -3
- data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +34 -0
- data/spec/rubocop/cop/style/percent_q_literals_spec.rb +122 -0
- data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +20 -0
- data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +26 -2
- data/spec/rubocop/cop/style/trailing_comma_spec.rb +112 -0
- data/spec/rubocop/cop/style/unneeded_percent_q_spec.rb +86 -31
- data/spec/rubocop/cop/style/variable_interpolation_spec.rb +21 -1
- data/spec/rubocop/cop/team_spec.rb +14 -9
- data/spec/spec_helper.rb +1 -0
- metadata +47 -50
- data/lib/rubocop/cop/mixin/if_then_else.rb +0 -23
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Metrics
|
6
|
+
# This cop tries to produce a complexity score that's a measure of the
|
7
|
+
# complexity the reader experiences when looking at a method. For that
|
8
|
+
# reason it considers `when` nodes as something that doesn't add as much
|
9
|
+
# complexity as an `if` or a `&&`. Except if it's one of those special
|
10
|
+
# `case`/`when` constructs where there's no expression after `case`. Then
|
11
|
+
# the cop treats it as an `if`/`elsif`/`elsif`... and lets all the `when`
|
12
|
+
# nodes count. In contrast to the CyclomaticComplexity cop, this cop
|
13
|
+
# considers `else` nodes as adding complexity.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# def my_method # 1
|
18
|
+
# if cond # 1
|
19
|
+
# case var # 2 (0.8 + 4 * 0.2, rounded)
|
20
|
+
# when 1 then func_one
|
21
|
+
# when 2 then func_two
|
22
|
+
# when 3 then func_three
|
23
|
+
# when 4..10 then func_other
|
24
|
+
# end
|
25
|
+
# else # 1
|
26
|
+
# do_something until a && b # 2
|
27
|
+
# end # ===
|
28
|
+
# end # 7 complexity points
|
29
|
+
class PerceivedComplexity < Cop
|
30
|
+
include MethodComplexity
|
31
|
+
include IfNode
|
32
|
+
|
33
|
+
MSG = 'Perceived complexity for %s is too high. [%d/%d]'
|
34
|
+
COUNTED_NODES = [:if, :case, :while, :until, :for, :rescue, :and, :or]
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def complexity_score_for(node)
|
39
|
+
case node.type
|
40
|
+
when :case
|
41
|
+
expression, *whens, _else = *node
|
42
|
+
# If cond is nil, that means each when has an expression that
|
43
|
+
# evaluates to true or false. It's just an alternative to
|
44
|
+
# if/elsif/elsif... so the when nodes count.
|
45
|
+
if expression.nil?
|
46
|
+
whens.length
|
47
|
+
else
|
48
|
+
# Otherwise, the case node gets 0.8 complexity points and each
|
49
|
+
# when gets 0.2.
|
50
|
+
(0.8 + 0.2 * whens.length).round
|
51
|
+
end
|
52
|
+
when :if
|
53
|
+
if_else?(node) && !elsif?(node) ? 2 : 1
|
54
|
+
else
|
55
|
+
1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -10,14 +10,22 @@ module RuboCop
|
|
10
10
|
c = correction(node)
|
11
11
|
new_source = rewrite_node(node)
|
12
12
|
|
13
|
-
# Make the correction only if it doesn't change the AST.
|
14
|
-
|
13
|
+
# Make the correction only if it doesn't change the AST. Regenerate the
|
14
|
+
# AST for `node` so we get it without context. Otherwise the comparison
|
15
|
+
# could be misleading.
|
16
|
+
if ast_for(node.loc.expression.source) != ast_for(new_source)
|
15
17
|
fail CorrectionNotPossible
|
16
18
|
end
|
17
19
|
|
18
20
|
@corrections << c
|
19
21
|
end
|
20
22
|
|
23
|
+
private
|
24
|
+
|
25
|
+
def ast_for(source)
|
26
|
+
ProcessedSource.new(source).ast
|
27
|
+
end
|
28
|
+
|
21
29
|
def rewrite_node(node)
|
22
30
|
processed_source = ProcessedSource.new(node.loc.expression.source)
|
23
31
|
c = correction(processed_source.ast)
|
@@ -14,12 +14,11 @@ module RuboCop
|
|
14
14
|
cop_config['CountComments']
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def check_code_length(node, *_)
|
18
18
|
length = code_length(node)
|
19
19
|
return unless length > max_length
|
20
20
|
|
21
|
-
add_offense(node, :keyword,
|
22
|
-
max_length)) do
|
21
|
+
add_offense(node, :keyword, message(length, max_length)) do
|
23
22
|
self.max = length
|
24
23
|
end
|
25
24
|
end
|
@@ -10,35 +10,21 @@ module RuboCop
|
|
10
10
|
SNAKE_CASE = /^@?[\da-z_]+[!?=]?$/
|
11
11
|
CAMEL_CASE = /^@?[a-z][\da-zA-Z]+[!?=]?$/
|
12
12
|
|
13
|
-
def
|
14
|
-
return unless range
|
15
|
-
|
16
|
-
name = range.source.to_sym
|
13
|
+
def check_name(node, name, name_range)
|
17
14
|
return if operator?(name)
|
18
15
|
|
19
|
-
if
|
16
|
+
if valid_name?(name)
|
20
17
|
correct_style_detected
|
21
18
|
else
|
22
|
-
add_offense(node,
|
19
|
+
add_offense(node, name_range, message(style)) do
|
23
20
|
opposite_style_detected
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# Returns a range containing the method name after the given regexp and
|
33
|
-
# a dot.
|
34
|
-
def after_dot(node, method_name_length, regexp)
|
35
|
-
expr = node.loc.expression
|
36
|
-
match = /\A#{regexp}\s*\.\s*/.match(expr.source)
|
37
|
-
return unless match
|
38
|
-
offset = match[0].length
|
39
|
-
begin_pos = expr.begin_pos + offset
|
40
|
-
Parser::Source::Range.new(expr.source_buffer, begin_pos,
|
41
|
-
begin_pos + method_name_length)
|
25
|
+
def valid_name?(name)
|
26
|
+
pattern = (style == :snake_case ? SNAKE_CASE : CAMEL_CASE)
|
27
|
+
name.match(pattern)
|
42
28
|
end
|
43
29
|
end
|
44
30
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module handles measurement and reporting of complexity in methods.
|
6
|
+
module MethodComplexity
|
7
|
+
include OnMethod
|
8
|
+
include ConfigurableMax
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def on_method(node, method_name, _args, _body)
|
13
|
+
max = cop_config['Max']
|
14
|
+
complexity = complexity(node)
|
15
|
+
return unless complexity > max
|
16
|
+
|
17
|
+
add_offense(node, :keyword,
|
18
|
+
format(self.class::MSG, method_name, complexity, max)) do
|
19
|
+
self.max = complexity
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def complexity(node)
|
24
|
+
c = 1
|
25
|
+
on_node(self.class::COUNTED_NODES, node) do |n|
|
26
|
+
c += complexity_score_for(n)
|
27
|
+
end
|
28
|
+
c
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
# Some common code shared between FavorUnlessOverNegatedIf and
|
6
6
|
# FavorUntilOverNegatedWhile.
|
7
7
|
module NegativeConditional
|
8
|
-
def
|
8
|
+
def check_negative_conditional(node)
|
9
9
|
condition, _body, _rest = *node
|
10
10
|
|
11
11
|
# Look at last expression of contents if there's a parenthesis
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
# Common functionality for checking instance methods and singeton methods.
|
6
|
-
module
|
6
|
+
module OnMethod
|
7
7
|
def on_def(node)
|
8
8
|
method_name, args, body = *node
|
9
|
-
|
9
|
+
on_method(node, method_name, args, body)
|
10
10
|
end
|
11
11
|
|
12
12
|
def on_defs(node)
|
13
13
|
_scope, method_name, args, body = *node
|
14
|
-
|
14
|
+
on_method(node, method_name, args, body)
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for cops checking if and unless statements.
|
6
|
+
module OnNormalIfUnless
|
7
|
+
include IfNode
|
8
|
+
|
9
|
+
def on_if(node)
|
10
|
+
invoke_hook_for_normal_if_unless(node)
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_unless(node)
|
14
|
+
invoke_hook_for_normal_if_unless(node)
|
15
|
+
end
|
16
|
+
|
17
|
+
def invoke_hook_for_normal_if_unless(node)
|
18
|
+
# We won't check modifier or ternary conditionals.
|
19
|
+
return if modifier_if?(node) || ternary_op?(node)
|
20
|
+
on_normal_if_unless(node)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
# Common functionality for checking for spaces inside various
|
6
|
-
# kinds of
|
6
|
+
# kinds of brackets.
|
7
7
|
module SpaceInside
|
8
8
|
include SurroundingSpace
|
9
9
|
MSG = 'Space inside %s detected.'
|
10
10
|
|
11
11
|
def investigate(processed_source)
|
12
12
|
@processed_source = processed_source
|
13
|
-
|
13
|
+
brackets = Brackets.new(*specifics)
|
14
14
|
processed_source.tokens.each_cons(2) do |t1, t2|
|
15
|
-
next unless t1
|
15
|
+
next unless brackets.left_side?(t1) || brackets.right_side?(t2)
|
16
16
|
|
17
17
|
# If the second token is a comment, that means that a line break
|
18
18
|
# follows, and that the rules for space inside don't apply.
|
@@ -22,13 +22,42 @@ module RuboCop
|
|
22
22
|
range = Parser::Source::Range.new(processed_source.buffer,
|
23
23
|
t1.pos.end_pos,
|
24
24
|
t2.pos.begin_pos)
|
25
|
-
add_offense(range, range, format(MSG, kind))
|
25
|
+
add_offense(range, range, format(MSG, brackets.kind))
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def autocorrect(range)
|
30
30
|
@corrections << ->(corrector) { corrector.remove(range) }
|
31
31
|
end
|
32
|
+
|
33
|
+
# Wraps info about the brackets. Makes it easy to check whether a token
|
34
|
+
# is one of the brackets.
|
35
|
+
#
|
36
|
+
# @example Parentheses `()`
|
37
|
+
# Brackets.new(:tLPAREN, :tRPAREN, 'parentheses')
|
38
|
+
#
|
39
|
+
# @example Square brackets `[]`
|
40
|
+
# Brackets.new([:tLBRACK, :tLBRACK2], :tRBRACK, 'square brackets')
|
41
|
+
#
|
42
|
+
class Brackets
|
43
|
+
attr_reader :kind
|
44
|
+
|
45
|
+
def initialize(left, right, kind)
|
46
|
+
@left_side_types = [left].flatten
|
47
|
+
@right_side_type = right
|
48
|
+
@kind = kind
|
49
|
+
end
|
50
|
+
|
51
|
+
def left_side?(token)
|
52
|
+
# Left side bracket has to be able to match multiple types
|
53
|
+
# (e.g. :tLBRACK and :tLBRACK2)
|
54
|
+
@left_side_types.include?(token.type)
|
55
|
+
end
|
56
|
+
|
57
|
+
def right_side?(token)
|
58
|
+
@right_side_type == token.type
|
59
|
+
end
|
60
|
+
end
|
32
61
|
end
|
33
62
|
end
|
34
63
|
end
|
@@ -7,14 +7,14 @@ module RuboCop
|
|
7
7
|
include IfNode
|
8
8
|
|
9
9
|
# TODO: Extremely ugly solution that needs lots of polish.
|
10
|
-
def
|
11
|
-
case
|
12
|
-
when 'if' then cond, body, _else = *
|
13
|
-
when 'unless' then cond, _else, body = *
|
14
|
-
else cond, body = *
|
10
|
+
def fit_within_line_as_modifier_form?(node)
|
11
|
+
case node.loc.keyword.source
|
12
|
+
when 'if' then cond, body, _else = *node
|
13
|
+
when 'unless' then cond, _else, body = *node
|
14
|
+
else cond, body = *node
|
15
15
|
end
|
16
16
|
|
17
|
-
return false if length(
|
17
|
+
return false if length(node) > 3
|
18
18
|
|
19
19
|
body_length = body_length(body)
|
20
20
|
|
@@ -24,22 +24,22 @@ module RuboCop
|
|
24
24
|
return false
|
25
25
|
end
|
26
26
|
|
27
|
-
indentation =
|
28
|
-
kw_length =
|
27
|
+
indentation = node.loc.keyword.column
|
28
|
+
kw_length = node.loc.keyword.size
|
29
29
|
cond_length = cond.loc.expression.size
|
30
30
|
space = 1
|
31
31
|
total = indentation + body_length + space + kw_length + space +
|
32
32
|
cond_length
|
33
|
-
total <= max_line_length && !body_has_comment?(body
|
33
|
+
total <= max_line_length && !body_has_comment?(body)
|
34
34
|
end
|
35
35
|
|
36
36
|
def max_line_length
|
37
37
|
cop_config && cop_config['MaxLineLength'] ||
|
38
|
-
config.for_cop('
|
38
|
+
config.for_cop('Metrics/LineLength')['Max']
|
39
39
|
end
|
40
40
|
|
41
|
-
def length(
|
42
|
-
|
41
|
+
def length(node)
|
42
|
+
node.loc.expression.source.lines.to_a.size
|
43
43
|
end
|
44
44
|
|
45
45
|
def body_length(body)
|
@@ -50,8 +50,8 @@ module RuboCop
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def body_has_comment?(body
|
54
|
-
comment_lines = comments.map(&:location).map(&:line)
|
53
|
+
def body_has_comment?(body)
|
54
|
+
comment_lines = processed_source.comments.map(&:location).map(&:line)
|
55
55
|
body_line = body.loc.expression.line
|
56
56
|
comment_lines.include?(body_line)
|
57
57
|
end
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
7
7
|
# adding offenses for the faulty string nodes, and with filtering out
|
8
8
|
# nodes.
|
9
9
|
module StringHelp
|
10
|
+
# Regex matches IF there is a ' or there is a \\ in the string that is
|
11
|
+
# not preceeded/followed by another \\ (e.g. "\\x34") but not "\\\\".
|
12
|
+
ESCAPED_CHAR_REGEXP = /(?<! \\) \\{2}* \\ (?! \\)/x
|
13
|
+
|
10
14
|
def on_str(node)
|
11
15
|
# Constants like __FILE__ are handled as strings,
|
12
16
|
# but don't respond to begin.
|
@@ -8,6 +8,7 @@ module RuboCop
|
|
8
8
|
between = Parser::Source::Range.new(t1.pos.source_buffer,
|
9
9
|
t1.pos.end_pos,
|
10
10
|
t2.pos.begin_pos).source
|
11
|
+
|
11
12
|
# Check if the range between the tokens starts with a space. It can
|
12
13
|
# contain other characters, e.g. a unary plus, but it must start with
|
13
14
|
# space.
|
@@ -29,13 +29,13 @@ module RuboCop
|
|
29
29
|
# foo.bar
|
30
30
|
# end
|
31
31
|
class Delegate < Cop
|
32
|
-
include
|
32
|
+
include OnMethod
|
33
33
|
|
34
34
|
MSG = 'Use `delegate` to define delegations.'
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def
|
38
|
+
def on_method(node, method_name, args, body)
|
39
39
|
return unless trivial_delegate?(method_name, args, body)
|
40
40
|
return if private_or_protected_delegation(node)
|
41
41
|
add_offense(node, :keyword, MSG)
|
@@ -14,8 +14,10 @@ module RuboCop
|
|
14
14
|
:pretty_print]
|
15
15
|
|
16
16
|
def on_send(node)
|
17
|
-
receiver, method_name, *
|
18
|
-
return unless receiver.nil? &&
|
17
|
+
receiver, method_name, *args = *node
|
18
|
+
return unless receiver.nil? &&
|
19
|
+
!args.empty? &&
|
20
|
+
BLACKLIST.include?(method_name)
|
19
21
|
|
20
22
|
add_offense(node, :selector)
|
21
23
|
end
|