eager_eye 0.2.2 → 0.2.3
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/lib/eager_eye/detectors/custom_method_query.rb +51 -7
- data/lib/eager_eye/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 251f5ec97df15b5f85cbea7b1be3b7c95961f6ed133f4a69b721d76ebd7ad40e
|
|
4
|
+
data.tar.gz: ce06033abc65e06113af34789bf17a97badcfe8076675a45bf5ee59f5e19af79
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f24578b9ec1a121b1698e3d53d78ec570b12b3f5092289ca42adc421c89cd1a94566e5de6ff45309803c0be2b8bafc76b1ea3e9f78599da32aef87503c51c38
|
|
7
|
+
data.tar.gz: 3f9dd3a3a3d4116840d8de2392e06afa78486ae049505f8706a7e5c9303d25e7efcf0ba7522b256bb9e504c1d8b709d93e06e92b1d0391cfd0e3bafdb7e00536
|
|
@@ -21,6 +21,9 @@ module EagerEye
|
|
|
21
21
|
maximum
|
|
22
22
|
].freeze
|
|
23
23
|
|
|
24
|
+
# Array-only methods that should not be flagged when collection is clearly an array
|
|
25
|
+
ARRAY_METHODS = %i[first last take].freeze
|
|
26
|
+
|
|
24
27
|
ITERATION_METHODS = %i[each map select find_all reject collect detect find_index flat_map].freeze
|
|
25
28
|
|
|
26
29
|
def self.detector_name
|
|
@@ -33,8 +36,9 @@ module EagerEye
|
|
|
33
36
|
@issues = []
|
|
34
37
|
@file_path = file_path
|
|
35
38
|
|
|
36
|
-
find_iteration_blocks(ast) do |block_body, block_var|
|
|
37
|
-
|
|
39
|
+
find_iteration_blocks(ast) do |block_body, block_var, collection|
|
|
40
|
+
is_array_collection = collection_is_array?(collection)
|
|
41
|
+
check_block_for_query_methods(block_body, block_var, is_array_collection)
|
|
38
42
|
end
|
|
39
43
|
|
|
40
44
|
@issues
|
|
@@ -48,7 +52,8 @@ module EagerEye
|
|
|
48
52
|
if iteration_block?(node)
|
|
49
53
|
block_var = extract_block_variable(node)
|
|
50
54
|
block_body = extract_block_body(node)
|
|
51
|
-
|
|
55
|
+
collection = extract_collection(node)
|
|
56
|
+
yield(block_body, block_var, collection) if block_var && block_body
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
node.children.each do |child|
|
|
@@ -66,26 +71,40 @@ module EagerEye
|
|
|
66
71
|
ITERATION_METHODS.include?(method_name)
|
|
67
72
|
end
|
|
68
73
|
|
|
69
|
-
def check_block_for_query_methods(node, block_var)
|
|
74
|
+
def check_block_for_query_methods(node, block_var, is_array_collection = false) # rubocop:disable Style/OptionalBooleanParameter
|
|
70
75
|
return unless node.is_a?(Parser::AST::Node)
|
|
71
76
|
|
|
72
|
-
add_issue(node) if query_chain_on_association?(node, block_var)
|
|
77
|
+
add_issue(node) if query_chain_on_association?(node, block_var, is_array_collection)
|
|
73
78
|
|
|
74
79
|
node.children.each do |child|
|
|
75
|
-
check_block_for_query_methods(child, block_var)
|
|
80
|
+
check_block_for_query_methods(child, block_var, is_array_collection)
|
|
76
81
|
end
|
|
77
82
|
end
|
|
78
83
|
|
|
79
|
-
def query_chain_on_association?(node, block_var)
|
|
84
|
+
def query_chain_on_association?(node, block_var, is_array_collection = false) # rubocop:disable Style/OptionalBooleanParameter
|
|
80
85
|
return false unless node.type == :send
|
|
81
86
|
|
|
82
87
|
method_name = node.children[1]
|
|
83
88
|
return false unless QUERY_METHODS.include?(method_name)
|
|
84
89
|
|
|
90
|
+
# Skip array-only methods when collection is clearly an array (.map result)
|
|
91
|
+
# AND the receiver is only the block variable (not chained)
|
|
92
|
+
if is_array_collection && ARRAY_METHODS.include?(method_name) &&
|
|
93
|
+
receiver_is_only_block_var?(node.children[0], block_var)
|
|
94
|
+
return false
|
|
95
|
+
end
|
|
96
|
+
|
|
85
97
|
receiver = node.children[0]
|
|
86
98
|
receiver_chain_starts_with?(receiver, block_var)
|
|
87
99
|
end
|
|
88
100
|
|
|
101
|
+
def receiver_is_only_block_var?(node, block_var)
|
|
102
|
+
# Returns true only if receiver is EXACTLY the block variable, not a chain
|
|
103
|
+
node.is_a?(Parser::AST::Node) &&
|
|
104
|
+
node.type == :lvar &&
|
|
105
|
+
node.children[0] == block_var
|
|
106
|
+
end
|
|
107
|
+
|
|
89
108
|
def receiver_chain_starts_with?(node, block_var)
|
|
90
109
|
return false unless node.is_a?(Parser::AST::Node)
|
|
91
110
|
|
|
@@ -113,6 +132,31 @@ module EagerEye
|
|
|
113
132
|
block_node.children[2]
|
|
114
133
|
end
|
|
115
134
|
|
|
135
|
+
def extract_collection(block_node)
|
|
136
|
+
# Extract the collection being iterated on
|
|
137
|
+
# For: collection.each { |item| ... }
|
|
138
|
+
# Returns: the send node representing the collection method call
|
|
139
|
+
block_node.children[0]
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def collection_is_array?(collection_node)
|
|
143
|
+
return false unless collection_node.is_a?(Parser::AST::Node)
|
|
144
|
+
|
|
145
|
+
case collection_node.type
|
|
146
|
+
when :array
|
|
147
|
+
# Literal array: [1, 2, 3].each { |item| ... }
|
|
148
|
+
true
|
|
149
|
+
when :send
|
|
150
|
+
# Only consider these methods as definitely returning arrays when iterating
|
|
151
|
+
method_name = collection_node.children[1]
|
|
152
|
+
# map, select, collect, etc. on anything return arrays for iteration
|
|
153
|
+
%i[map select collect flat_map to_a uniq compact].include?(method_name)
|
|
154
|
+
else
|
|
155
|
+
# Block variable itself won't tell us if it's an array
|
|
156
|
+
false
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
116
160
|
def add_issue(node)
|
|
117
161
|
method_name = node.children[1]
|
|
118
162
|
association_chain = reconstruct_chain(node.children[0])
|
data/lib/eager_eye/version.rb
CHANGED