rubocop 0.23.0 → 0.24.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/.travis.yml +1 -1
- data/CHANGELOG.md +35 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +6 -6
- data/config/default.yml +25 -6
- data/config/enabled.yml +20 -0
- data/lib/rubocop.rb +10 -13
- data/lib/rubocop/cli.rb +23 -20
- data/lib/rubocop/cop/lint/def_end_alignment.rb +47 -0
- data/lib/rubocop/cop/lint/end_alignment.rb +18 -65
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +28 -4
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -1
- data/lib/rubocop/cop/lint/unused_block_argument.rb +13 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -9
- data/lib/rubocop/cop/lint/useless_setter_call.rb +28 -20
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +18 -0
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +4 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +42 -0
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +32 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -8
- data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
- data/lib/rubocop/cop/offense.rb +27 -14
- data/lib/rubocop/cop/style/access_modifier_indentation.rb +2 -9
- data/lib/rubocop/cop/style/attr.rb +3 -1
- data/lib/rubocop/cop/style/class_check.rb +42 -0
- data/lib/rubocop/cop/style/each_with_object.rb +5 -1
- data/lib/rubocop/cop/style/empty_lines.rb +1 -4
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +2 -8
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +1 -4
- data/lib/rubocop/cop/style/encoding.rb +3 -5
- data/lib/rubocop/cop/style/end_of_line.rb +2 -5
- data/lib/rubocop/cop/style/file_name.rb +2 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -1
- data/lib/rubocop/cop/style/indentation_consistency.rb +2 -1
- data/lib/rubocop/cop/style/indentation_width.rb +25 -5
- data/lib/rubocop/cop/style/line_length.rb +59 -5
- data/lib/rubocop/cop/style/next.rb +18 -18
- data/lib/rubocop/cop/style/numeric_literals.rb +22 -9
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
- data/lib/rubocop/cop/style/redundant_self.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -3
- data/lib/rubocop/cop/style/space_after_colon.rb +7 -3
- data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +3 -1
- data/lib/rubocop/cop/style/space_before_comma.rb +16 -0
- data/lib/rubocop/cop/style/space_before_semicolon.rb +16 -0
- data/lib/rubocop/cop/style/tab.rb +6 -5
- data/lib/rubocop/cop/style/trailing_comma.rb +33 -6
- data/lib/rubocop/cop/style/trailing_whitespace.rb +4 -3
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +6 -0
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +45 -0
- data/lib/rubocop/cop/style/unneeded_percent_x.rb +2 -3
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/team.rb +6 -12
- data/lib/rubocop/cop/util.rb +26 -8
- data/lib/rubocop/cop/variable_force.rb +3 -6
- data/lib/rubocop/cop/variable_force/variable.rb +7 -3
- data/lib/rubocop/processed_source.rb +52 -12
- data/lib/rubocop/{file_inspector.rb → runner.rb} +50 -59
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.24.0.md +77 -0
- data/rubocop.gemspec +4 -4
- data/spec/rubocop/cli_spec.rb +38 -21
- data/spec/rubocop/config_loader_spec.rb +7 -6
- data/spec/rubocop/config_spec.rb +8 -8
- data/spec/rubocop/cop/cop_spec.rb +1 -1
- data/spec/rubocop/cop/lint/def_end_alignment_spec.rb +108 -0
- data/spec/rubocop/cop/lint/end_alignment_spec.rb +0 -47
- data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +6 -7
- data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +19 -0
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +8 -18
- data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +99 -51
- data/spec/rubocop/cop/offense_spec.rb +3 -3
- data/spec/rubocop/cop/rails/delegate_spec.rb +1 -1
- data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +12 -0
- data/spec/rubocop/cop/style/align_hash_spec.rb +4 -4
- data/spec/rubocop/cop/style/align_parameters_spec.rb +1 -1
- data/spec/rubocop/cop/style/attr_spec.rb +12 -2
- data/spec/rubocop/cop/style/class_check_spec.rb +41 -0
- data/spec/rubocop/cop/style/each_with_object_spec.rb +5 -0
- data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +5 -0
- data/spec/rubocop/cop/style/indentation_width_spec.rb +95 -0
- data/spec/rubocop/cop/style/line_length_spec.rb +75 -0
- data/spec/rubocop/cop/style/next_spec.rb +28 -0
- data/spec/rubocop/cop/style/numeric_literals_spec.rb +10 -0
- data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +5 -0
- data/spec/rubocop/cop/style/space_after_colon_spec.rb +17 -0
- data/spec/rubocop/cop/style/space_around_equals_in_parameter_default_spec.rb +11 -0
- data/spec/rubocop/cop/style/space_around_operators_spec.rb +1 -0
- data/spec/rubocop/cop/style/space_before_comma_spec.rb +42 -0
- data/spec/rubocop/cop/style/space_before_semicolon_spec.rb +28 -0
- data/spec/rubocop/cop/style/trailing_comma_spec.rb +37 -15
- data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +8 -10
- data/spec/rubocop/cop/style/unneeded_percent_q_spec.rb +72 -0
- data/spec/rubocop/cop/style/word_array_spec.rb +6 -0
- data/spec/rubocop/cop/team_spec.rb +8 -8
- data/spec/rubocop/cop/util_spec.rb +10 -0
- data/spec/rubocop/cop/variable_force/assignment_spec.rb +1 -1
- data/spec/rubocop/cop/variable_force/locatable_spec.rb +1 -1
- data/spec/rubocop/cop/variable_force/scope_spec.rb +1 -1
- data/spec/rubocop/cop/variable_force/variable_spec.rb +4 -4
- data/spec/rubocop/formatter/base_formatter_spec.rb +5 -5
- data/spec/rubocop/formatter/colorizable_spec.rb +2 -2
- data/spec/rubocop/formatter/json_formatter_spec.rb +1 -1
- data/spec/rubocop/path_util_spec.rb +15 -15
- data/spec/rubocop/processed_source_spec.rb +104 -50
- data/spec/rubocop/runner_spec.rb +64 -0
- data/spec/spec_helper.rb +8 -10
- data/spec/support/shared_examples.rb +22 -0
- metadata +39 -15
- data/lib/rubocop/source_parser.rb +0 -47
- data/spec/rubocop/file_inspector_spec.rb +0 -84
- data/spec/rubocop/source_parser_spec.rb +0 -85
@@ -7,18 +7,18 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# Two modes are supported through the AlignWith configuration
|
9
9
|
# parameter. If it's set to `keyword` (which is the default), the `end`
|
10
|
-
# shall be aligned with the start of the keyword (if,
|
11
|
-
# set to `variable` the `end` shall be aligned with the
|
12
|
-
# the variable assignment, if there is one.
|
10
|
+
# shall be aligned with the start of the keyword (if, class, etc.). If
|
11
|
+
# it's set to `variable` the `end` shall be aligned with the
|
12
|
+
# left-hand-side of the variable assignment, if there is one.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
#
|
16
16
|
# variable = if true
|
17
17
|
# end
|
18
18
|
class EndAlignment < Cop
|
19
|
-
include CheckMethods
|
20
19
|
include CheckAssignment
|
21
|
-
include
|
20
|
+
include EndKeywordAlignment
|
21
|
+
include IfNode
|
22
22
|
|
23
23
|
MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d'
|
24
24
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def on_if(node)
|
34
|
-
check(node)
|
34
|
+
check(node) unless ternary_op?(node)
|
35
35
|
end
|
36
36
|
|
37
37
|
def on_while(node)
|
@@ -42,23 +42,6 @@ module RuboCop
|
|
42
42
|
check(node)
|
43
43
|
end
|
44
44
|
|
45
|
-
def on_send(node)
|
46
|
-
super
|
47
|
-
|
48
|
-
receiver, method_name, *args = *node
|
49
|
-
return unless visibility_and_def_on_same_line?(receiver, method_name,
|
50
|
-
args)
|
51
|
-
|
52
|
-
expr = node.loc.expression
|
53
|
-
method_def = args.first
|
54
|
-
range = Parser::Source::Range.new(expr.source_buffer,
|
55
|
-
expr.begin_pos,
|
56
|
-
method_def.loc.keyword.end_pos)
|
57
|
-
check_offset(method_def, range.source,
|
58
|
-
method_def.loc.keyword.begin_pos - expr.begin_pos)
|
59
|
-
ignore_node(method_def) # Don't check the same `end` again.
|
60
|
-
end
|
61
|
-
|
62
45
|
private
|
63
46
|
|
64
47
|
def check_assignment(node, rhs)
|
@@ -69,52 +52,22 @@ module RuboCop
|
|
69
52
|
|
70
53
|
return unless rhs
|
71
54
|
|
72
|
-
|
73
|
-
|
74
|
-
return if rhs.loc.respond_to?(:question) # ternary
|
75
|
-
|
76
|
-
if style == :variable
|
77
|
-
expr = node.loc.expression
|
78
|
-
range = Parser::Source::Range.new(expr.source_buffer,
|
79
|
-
expr.begin_pos,
|
80
|
-
rhs.loc.keyword.end_pos)
|
81
|
-
offset = rhs.loc.keyword.column - node.loc.expression.column
|
82
|
-
else
|
83
|
-
range = rhs.loc.keyword
|
84
|
-
offset = 0
|
85
|
-
end
|
86
|
-
|
87
|
-
check_offset(rhs, range.source, offset)
|
88
|
-
ignore_node(rhs) # Don't check again.
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def check(node, *_)
|
93
|
-
check_offset(node, node.loc.keyword.source, 0)
|
94
|
-
end
|
95
|
-
|
96
|
-
def check_offset(node, alignment_base, offset)
|
97
|
-
return if ignored_node?(node)
|
55
|
+
return unless [:if, :while, :until].include?(rhs.type)
|
56
|
+
return if ternary_op?(rhs)
|
98
57
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
kw_loc.column != end_loc.column + offset
|
106
|
-
add_offense(nil, end_loc,
|
107
|
-
format(MSG, end_loc.line, end_loc.column,
|
108
|
-
alignment_base, kw_loc.line, kw_loc.column)) do
|
109
|
-
opposite_style_detected
|
110
|
-
end
|
58
|
+
if style == :variable
|
59
|
+
expr = node.loc.expression
|
60
|
+
range = Parser::Source::Range.new(expr.source_buffer,
|
61
|
+
expr.begin_pos,
|
62
|
+
rhs.loc.keyword.end_pos)
|
63
|
+
offset = rhs.loc.keyword.column - node.loc.expression.column
|
111
64
|
else
|
112
|
-
|
65
|
+
range = rhs.loc.keyword
|
66
|
+
offset = 0
|
113
67
|
end
|
114
|
-
end
|
115
68
|
|
116
|
-
|
117
|
-
'
|
69
|
+
check_offset(rhs, range.source, offset)
|
70
|
+
ignore_node(rhs) # Don't check again.
|
118
71
|
end
|
119
72
|
end
|
120
73
|
end
|
@@ -15,7 +15,7 @@ module RuboCop
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def before_declaring_variable(variable, variable_table)
|
18
|
-
return if variable.
|
18
|
+
return if variable.should_be_unused?
|
19
19
|
|
20
20
|
outer_local_variable = variable_table.find_variable(variable.name)
|
21
21
|
return unless outer_local_variable
|
@@ -4,14 +4,25 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
6
|
# This is actually not a cop and inspects nothing. It just provides
|
7
|
-
# methods to repack Parser's diagnostics into RuboCop's offenses.
|
7
|
+
# methods to repack Parser's diagnostics/errors into RuboCop's offenses.
|
8
8
|
module Syntax
|
9
|
+
PseudoSourceRange = Struct.new(:line, :column, :source_line)
|
10
|
+
|
9
11
|
COP_NAME = 'Syntax'.freeze
|
12
|
+
ERROR_SOURCE_RANGE = PseudoSourceRange.new(1, 0, '').freeze
|
13
|
+
|
14
|
+
def self.offenses_from_processed_source(processed_source)
|
15
|
+
offenses = []
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
offense_from_diagnostic(diagnostic)
|
17
|
+
if processed_source.parser_error
|
18
|
+
offenses << offense_from_error(processed_source.parser_error)
|
14
19
|
end
|
20
|
+
|
21
|
+
processed_source.diagnostics.each do |diagnostic|
|
22
|
+
offenses << offense_from_diagnostic(diagnostic)
|
23
|
+
end
|
24
|
+
|
25
|
+
offenses
|
15
26
|
end
|
16
27
|
|
17
28
|
def self.offense_from_diagnostic(diagnostic)
|
@@ -22,6 +33,19 @@ module RuboCop
|
|
22
33
|
COP_NAME
|
23
34
|
)
|
24
35
|
end
|
36
|
+
|
37
|
+
def self.offense_from_error(error)
|
38
|
+
message = beautify_message(error.message)
|
39
|
+
Offense.new(:fatal, ERROR_SOURCE_RANGE, message, COP_NAME)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.beautify_message(message)
|
43
|
+
message = message.capitalize
|
44
|
+
message << '.' unless message.end_with?('.')
|
45
|
+
message
|
46
|
+
end
|
47
|
+
|
48
|
+
private_class_method :beautify_message
|
25
49
|
end
|
26
50
|
end
|
27
51
|
end
|
@@ -20,7 +20,11 @@ module RuboCop
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def message(variable)
|
23
|
-
message = "Unused
|
23
|
+
message = "Unused #{variable_type(variable)} - `#{variable.name}`."
|
24
|
+
|
25
|
+
return message if variable.explicit_block_local_variable?
|
26
|
+
|
27
|
+
message << ' '
|
24
28
|
|
25
29
|
scope = variable.scope
|
26
30
|
all_arguments = scope.variables.each_value.select(&:block_argument?)
|
@@ -34,6 +38,14 @@ module RuboCop
|
|
34
38
|
message
|
35
39
|
end
|
36
40
|
|
41
|
+
def variable_type(variable)
|
42
|
+
if variable.explicit_block_local_variable?
|
43
|
+
'block local variable'
|
44
|
+
else
|
45
|
+
'block argument'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
37
49
|
def message_for_normal_block(variable, all_arguments)
|
38
50
|
if all_arguments.none?(&:referenced?)
|
39
51
|
if all_arguments.count > 1
|
@@ -12,6 +12,8 @@ module RuboCop
|
|
12
12
|
# end
|
13
13
|
# end
|
14
14
|
class UselessAccessModifier < Cop
|
15
|
+
include AccessModifierNode
|
16
|
+
|
15
17
|
MSG = 'Useless `%s` access modifier.'
|
16
18
|
|
17
19
|
def on_class(node)
|
@@ -46,8 +48,7 @@ module RuboCop
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def check_for_access_modifier(node)
|
49
|
-
return unless
|
50
|
-
.modifier_node?(node)
|
51
|
+
return unless modifier_node?(node)
|
51
52
|
|
52
53
|
add_offense_for_access_modifier
|
53
54
|
@access_modifier_node = node
|
@@ -22,12 +22,11 @@ module RuboCop
|
|
22
22
|
def after_leaving_scope(scope, _variable_table)
|
23
23
|
scope.variables.each_value do |variable|
|
24
24
|
check_for_unused_assignments(variable)
|
25
|
-
check_for_unused_block_local_variable(variable)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
def check_for_unused_assignments(variable)
|
30
|
-
return if variable.
|
29
|
+
return if variable.should_be_unused?
|
31
30
|
|
32
31
|
variable.assignments.each do |assignment|
|
33
32
|
next if assignment.used?
|
@@ -73,13 +72,6 @@ module RuboCop
|
|
73
72
|
body_node
|
74
73
|
end
|
75
74
|
end
|
76
|
-
|
77
|
-
def check_for_unused_block_local_variable(variable)
|
78
|
-
return unless variable.block_local_variable?
|
79
|
-
return unless variable.assignments.empty?
|
80
|
-
message = format(MSG, variable.name)
|
81
|
-
add_offense(variable.declaration_node, :expression, message)
|
82
|
-
end
|
83
75
|
end
|
84
76
|
end
|
85
77
|
end
|
@@ -17,10 +17,17 @@ module RuboCop
|
|
17
17
|
|
18
18
|
MSG = 'Useless setter call to local variable `%s`.'
|
19
19
|
ASSIGNMENT_TYPES = [:lvasgn, :ivasgn, :cvasgn, :gvasgn].freeze
|
20
|
+
LITERAL_TYPES = [
|
21
|
+
:true, :false, :nil,
|
22
|
+
:int, :float,
|
23
|
+
:str, :dstr, :sym, :dsym, :xstr, :regexp,
|
24
|
+
:array, :hash,
|
25
|
+
:irange, :erange
|
26
|
+
].freeze
|
20
27
|
|
21
28
|
private
|
22
29
|
|
23
|
-
def check(_node, _method_name,
|
30
|
+
def check(_node, _method_name, _args, body)
|
24
31
|
return unless body
|
25
32
|
|
26
33
|
if body.type == :begin
|
@@ -33,10 +40,10 @@ module RuboCop
|
|
33
40
|
|
34
41
|
return unless setter_call_to_local_variable?(last_expr)
|
35
42
|
|
36
|
-
tracker = MethodVariableTracker.new(
|
43
|
+
tracker = MethodVariableTracker.new(body)
|
37
44
|
receiver, = *last_expr
|
38
|
-
|
39
|
-
return
|
45
|
+
variable_name, = *receiver
|
46
|
+
return unless tracker.contain_local_object?(variable_name)
|
40
47
|
|
41
48
|
add_offense(receiver,
|
42
49
|
:name,
|
@@ -47,27 +54,21 @@ module RuboCop
|
|
47
54
|
return unless node && node.type == :send
|
48
55
|
receiver, method, _args = *node
|
49
56
|
return unless receiver && receiver.type == :lvar
|
50
|
-
method =~
|
57
|
+
method =~ /(?:\w|\[\])=$/
|
51
58
|
end
|
52
59
|
|
53
60
|
# This class tracks variable assignments in a method body
|
54
61
|
# and if a variable contains object passed as argument at the end of
|
55
62
|
# the method.
|
56
63
|
class MethodVariableTracker
|
57
|
-
def initialize(
|
58
|
-
@args_node = args_node
|
64
|
+
def initialize(body_node)
|
59
65
|
@body_node = body_node
|
60
66
|
end
|
61
67
|
|
62
|
-
def
|
63
|
-
return @
|
68
|
+
def contain_local_object?(variable_name)
|
69
|
+
return @local[variable_name] if @table
|
64
70
|
|
65
|
-
@
|
66
|
-
|
67
|
-
@args_node.children.each do |arg_node|
|
68
|
-
arg_name, = *arg_node
|
69
|
-
@table[arg_name] = true
|
70
|
-
end
|
71
|
+
@local = {}
|
71
72
|
|
72
73
|
scan(@body_node) do |node|
|
73
74
|
case node.type
|
@@ -83,7 +84,7 @@ module RuboCop
|
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
86
|
-
@
|
87
|
+
@local[variable_name]
|
87
88
|
end
|
88
89
|
|
89
90
|
def scan(node, &block)
|
@@ -109,7 +110,7 @@ module RuboCop
|
|
109
110
|
if mrhs_node.type == :array && rhs_node
|
110
111
|
process_assignment(lhs_variable_name, rhs_node)
|
111
112
|
else
|
112
|
-
@
|
113
|
+
@local[lhs_variable_name] = true
|
113
114
|
end
|
114
115
|
end
|
115
116
|
|
@@ -128,7 +129,7 @@ module RuboCop
|
|
128
129
|
lhs_node, = *op_asgn_node
|
129
130
|
return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
|
130
131
|
lhs_variable_name, = *lhs_node
|
131
|
-
@
|
132
|
+
@local[lhs_variable_name] = true
|
132
133
|
|
133
134
|
throw :skip_children
|
134
135
|
end
|
@@ -138,11 +139,18 @@ module RuboCop
|
|
138
139
|
|
139
140
|
if [:lvar, :ivar, :cvar, :gvar].include?(rhs_node.type)
|
140
141
|
rhs_variable_name, = *rhs_node
|
141
|
-
@
|
142
|
+
@local[lhs_variable_name] = @local[rhs_variable_name]
|
142
143
|
else
|
143
|
-
@
|
144
|
+
@local[lhs_variable_name] = constructor?(rhs_node)
|
144
145
|
end
|
145
146
|
end
|
147
|
+
|
148
|
+
def constructor?(node)
|
149
|
+
return true if LITERAL_TYPES.include?(node.type)
|
150
|
+
return false unless node.type == :send
|
151
|
+
_receiver, method = *node
|
152
|
+
method == :new
|
153
|
+
end
|
146
154
|
end
|
147
155
|
end
|
148
156
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for checking modifier nodes.
|
6
|
+
module AccessModifierNode
|
7
|
+
extend AST::Sexp
|
8
|
+
|
9
|
+
PRIVATE_NODE = s(:send, nil, :private)
|
10
|
+
PROTECTED_NODE = s(:send, nil, :protected)
|
11
|
+
PUBLIC_NODE = s(:send, nil, :public)
|
12
|
+
|
13
|
+
def modifier_node?(node)
|
14
|
+
[PRIVATE_NODE, PROTECTED_NODE, PUBLIC_NODE].include?(node)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -11,13 +11,15 @@ module RuboCop
|
|
11
11
|
new_source = rewrite_node(node)
|
12
12
|
|
13
13
|
# Make the correction only if it doesn't change the AST.
|
14
|
-
|
14
|
+
if node != ProcessedSource.new(new_source).ast
|
15
|
+
fail CorrectionNotPossible
|
16
|
+
end
|
15
17
|
|
16
18
|
@corrections << c
|
17
19
|
end
|
18
20
|
|
19
21
|
def rewrite_node(node)
|
20
|
-
processed_source =
|
22
|
+
processed_source = ProcessedSource.new(node.loc.expression.source)
|
21
23
|
c = correction(processed_source.ast)
|
22
24
|
Corrector.new(processed_source.buffer, [c]).rewrite
|
23
25
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Functions for checking the alignment of the `end` keyword.
|
6
|
+
module EndKeywordAlignment
|
7
|
+
include ConfigurableEnforcedStyle
|
8
|
+
|
9
|
+
MSG = '`end` at %d, %d is not aligned with `%s` at %d, %d'
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def check(node, *_)
|
14
|
+
check_offset(node, node.loc.keyword.source, 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_offset(node, alignment_base, offset)
|
18
|
+
return if ignored_node?(node)
|
19
|
+
|
20
|
+
end_loc = node.loc.end
|
21
|
+
return unless end_loc # Discard modifier forms of if/while/until.
|
22
|
+
|
23
|
+
kw_loc = node.loc.keyword
|
24
|
+
|
25
|
+
if kw_loc.line != end_loc.line &&
|
26
|
+
kw_loc.column != end_loc.column + offset
|
27
|
+
add_offense(nil, end_loc,
|
28
|
+
format(MSG, end_loc.line, end_loc.column,
|
29
|
+
alignment_base, kw_loc.line, kw_loc.column)) do
|
30
|
+
opposite_style_detected
|
31
|
+
end
|
32
|
+
else
|
33
|
+
correct_style_detected
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parameter_name
|
38
|
+
'AlignWith'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|