rubocop-elegant 0.3.0 → 0.4.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0441b4d9f29a02a65680ffc46fb56985251723336a076999f7867ad7eb92185d
|
|
4
|
+
data.tar.gz: 92771eff5ed80253a14a85fd96ecaace40e7ce0476f2e26c6cb42372a26b9706
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1fd06eba3ce66013593a26400d81698fa3eeb01725890aa3ae5e0f78d086729b6b633f9d6a0551e61e2c1118ad844a12daba2ab97da5306ff13b8feb48a3d2b
|
|
7
|
+
data.tar.gz: 7595e8287a2f7f3904d643c98c1bafc412c2bfebcf4eb2de364ae13af4badf491985eba022f86cf93362efb997d0df57a171068a3ecc1ffb0b27d0c0cbf6e028
|
|
@@ -19,7 +19,19 @@
|
|
|
19
19
|
# whether or when the right-hand side is evaluated. A variable that
|
|
20
20
|
# is reassigned, read more than once, or never read is left alone
|
|
21
21
|
# too.
|
|
22
|
+
#
|
|
23
|
+
# Auto-correct inlines the redundant assignment: it replaces the
|
|
24
|
+
# single +lvar+ read with the source of the assignment's right-hand
|
|
25
|
+
# side, then removes the whole assignment line including its leading
|
|
26
|
+
# indent and trailing newline. The right-hand side is wrapped in
|
|
27
|
+
# parentheses unless it is already a primary expression (literal,
|
|
28
|
+
# variable, parenthesized expression, or method call with parentheses
|
|
29
|
+
# or no arguments), so that operator precedence at the read site is
|
|
30
|
+
# preserved.
|
|
22
31
|
class RuboCop::Cop::Elegant::NoRedundantVariable < RuboCop::Cop::Base
|
|
32
|
+
extend RuboCop::Cop::AutoCorrector
|
|
33
|
+
include RuboCop::Cop::RangeHelp
|
|
34
|
+
|
|
23
35
|
MSG = 'Variable "%<name>s" is redundant and must be inlined: it is read only once'
|
|
24
36
|
public_constant :MSG
|
|
25
37
|
|
|
@@ -35,6 +47,12 @@ class RuboCop::Cop::Elegant::NoRedundantVariable < RuboCop::Cop::Base
|
|
|
35
47
|
ALWAYS_HOIST_TYPES = %i[rescue resbody ensure].freeze
|
|
36
48
|
public_constant :ALWAYS_HOIST_TYPES
|
|
37
49
|
|
|
50
|
+
PRIMARY_TYPES = %i[
|
|
51
|
+
int float str sym dstr dsym xstr true false nil array hash regexp
|
|
52
|
+
lvar ivar cvar gvar const self nth_ref back_ref
|
|
53
|
+
].freeze
|
|
54
|
+
public_constant :PRIMARY_TYPES
|
|
55
|
+
|
|
38
56
|
def on_def(node)
|
|
39
57
|
check(node.body)
|
|
40
58
|
end
|
|
@@ -56,10 +74,52 @@ class RuboCop::Cop::Elegant::NoRedundantVariable < RuboCop::Cop::Base
|
|
|
56
74
|
next unless nodes.size == 1
|
|
57
75
|
next unless reads[name].size == 1
|
|
58
76
|
next if hoisted?(reads[name].first, nodes.first)
|
|
59
|
-
|
|
77
|
+
register(nodes.first, reads[name].first, name)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def register(assign, read, name)
|
|
82
|
+
return add_offense(assign, message: format(MSG, name: name)) unless solo?(assign)
|
|
83
|
+
add_offense(assign, message: format(MSG, name: name)) do |corrector|
|
|
84
|
+
corrector.replace(read.source_range, inlined(assign.children.last, read))
|
|
85
|
+
corrector.remove(range_by_whole_lines(assign.source_range, include_final_newline: true))
|
|
60
86
|
end
|
|
61
87
|
end
|
|
62
88
|
|
|
89
|
+
def solo?(assign)
|
|
90
|
+
range = assign.source_range
|
|
91
|
+
return false unless range.first_line == range.last_line
|
|
92
|
+
range.source_buffer.source_line(range.first_line).strip == range.source.strip
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def inlined(rhs, read)
|
|
96
|
+
return "(#{braced(rhs)})" if wrap?(rhs, read)
|
|
97
|
+
braced(rhs)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def braced(rhs)
|
|
101
|
+
return "{ #{rhs.source} }" if rhs.hash_type? && rhs.loc.begin.nil?
|
|
102
|
+
rhs.source
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def wrap?(rhs, read)
|
|
106
|
+
return true unless primary?(rhs)
|
|
107
|
+
rhs.hash_type? && bare?(read)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def primary?(node)
|
|
111
|
+
return true if PRIMARY_TYPES.include?(node.type)
|
|
112
|
+
return !node.loc.begin.nil? || node.arguments.empty? if node.send_type? || node.csend_type?
|
|
113
|
+
node.begin_type? && node.children.size == 1
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def bare?(read)
|
|
117
|
+
parent = read.parent
|
|
118
|
+
return false if parent.nil?
|
|
119
|
+
return false unless parent.send_type? || parent.csend_type?
|
|
120
|
+
parent.loc.begin.nil? && parent.arguments.include?(read)
|
|
121
|
+
end
|
|
122
|
+
|
|
63
123
|
def walk(node, assigns, reads, tainted)
|
|
64
124
|
return unless node.is_a?(RuboCop::AST::Node)
|
|
65
125
|
return if node.def_type? || node.defs_type?
|
|
@@ -9,8 +9,17 @@
|
|
|
9
9
|
# closing). Brackets stranded in the middle of a multi-line expression
|
|
10
10
|
# are forbidden because they hide the structure of the code.
|
|
11
11
|
#
|
|
12
|
+
# Auto-correct relocates the offending bracket onto its own line: an
|
|
13
|
+
# opener that is not at end-of-line gets a newline and the opener-line
|
|
14
|
+
# indent plus two spaces inserted right after it; a closer that is not
|
|
15
|
+
# at start-of-line gets a newline and the opener-line indent inserted
|
|
16
|
+
# right before it. Surrounding indentation may still need a follow-up
|
|
17
|
+
# layout pass, but the brackets themselves end up paired.
|
|
18
|
+
#
|
|
12
19
|
# See https://www.yegor256.com/2014/10/23/paired-brackets-notation.html
|
|
13
20
|
class RuboCop::Cop::Elegant::PairedBrackets < RuboCop::Cop::Base
|
|
21
|
+
extend RuboCop::Cop::AutoCorrector
|
|
22
|
+
|
|
14
23
|
MSG = 'Bracket %<text>s must be paired on the same line, or start/end its line'
|
|
15
24
|
public_constant :MSG
|
|
16
25
|
|
|
@@ -43,8 +52,9 @@ class RuboCop::Cop::Elegant::PairedBrackets < RuboCop::Cop::Base
|
|
|
43
52
|
def check(duo)
|
|
44
53
|
opener, closer = duo
|
|
45
54
|
return if opener.line == closer.line
|
|
46
|
-
|
|
47
|
-
register(
|
|
55
|
+
indent = leading(opener)
|
|
56
|
+
register(opener) { |corrector| corrector.insert_after(opener.pos, "\n#{indent} ") } unless ends?(opener)
|
|
57
|
+
register(closer) { |corrector| corrector.insert_before(closer.pos, "\n#{indent}") } unless starts?(closer)
|
|
48
58
|
end
|
|
49
59
|
|
|
50
60
|
def starts?(tok)
|
|
@@ -56,7 +66,11 @@ class RuboCop::Cop::Elegant::PairedBrackets < RuboCop::Cop::Base
|
|
|
56
66
|
after.empty? || after.start_with?('#')
|
|
57
67
|
end
|
|
58
68
|
|
|
59
|
-
def
|
|
60
|
-
|
|
69
|
+
def leading(tok)
|
|
70
|
+
processed_source.lines[tok.line - 1][/\A[ \t]*/]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def register(tok, &block)
|
|
74
|
+
add_offense(tok.pos, message: format(MSG, text: tok.text), &block)
|
|
61
75
|
end
|
|
62
76
|
end
|
data/rubocop-elegant.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to?(:required_rubygems_version=)
|
|
10
10
|
s.required_ruby_version = '>=2.2'
|
|
11
11
|
s.name = 'rubocop-elegant'
|
|
12
|
-
s.version = '0.
|
|
12
|
+
s.version = '0.4.0'
|
|
13
13
|
s.license = 'MIT'
|
|
14
14
|
s.summary = 'Set of custom RuboCop cops for elegant Ruby coding'
|
|
15
15
|
s.description =
|