@@ -51,55 +51,78 @@ def on_string_node_enter(node)
51
51
handle_possible_dsl ( node )
52
52
end
53
53
54
- #: ((Prism::SymbolNode | Prism::StringNode) node) -> void
55
- def handle_possible_dsl ( node )
56
- node = @node_context . call_node
57
- return unless node
54
+ #: (Prism::CallNode node) -> void
55
+ def on_call_node_enter ( node )
58
56
return unless self_receiver? ( node )
59
57
60
58
message = node . message
61
59
62
60
return unless message
63
61
64
- if Support ::Associations ::ALL . include? ( message )
65
- handle_association ( node )
66
- elsif Support ::Callbacks ::ALL . include? ( message )
67
- handle_callback ( node )
62
+ if message . end_with? ( "_path" ) || message . end_with? ( "_url" )
63
+ handle_route ( node )
68
64
end
69
65
end
70
66
71
- #: (Prism::CallNode node) -> void
72
- def on_call_node_enter ( node )
73
- return unless self_receiver? ( node )
67
+ private
74
68
75
- message = node . message
69
+ #: ((Prism::SymbolNode | Prism::StringNode) node) -> void
70
+ def handle_possible_dsl ( node )
71
+ call_node = @node_context . call_node
72
+ return unless call_node
73
+ return unless self_receiver? ( call_node )
74
+
75
+ message = call_node . message
76
76
77
77
return unless message
78
78
79
- if message . end_with? ( "_path" ) || message . end_with? ( "_url" )
80
- handle_route ( node )
79
+ arguments = call_node . arguments &.arguments
80
+ return unless arguments
81
+
82
+ if Support ::Associations ::ALL . include? ( message )
83
+ handle_association ( call_node )
84
+ elsif Support ::Callbacks ::ALL . include? ( message )
85
+ handle_callback ( node , call_node , arguments )
86
+ handle_if_unless_conditional ( node , call_node , arguments )
87
+ elsif Support ::Validations ::ALL . include? ( message )
88
+ handle_validation ( node , call_node , arguments )
89
+ handle_if_unless_conditional ( node , call_node , arguments )
81
90
end
82
91
end
83
92
84
- private
93
+ #: ((Prism::SymbolNode | Prism::StringNode) node, Prism::CallNode call_node, Array[Prism::Node] arguments) -> void
94
+ def handle_callback ( node , call_node , arguments )
95
+ focus_argument = arguments . find { |argument | argument == node }
85
96
86
- #: (Prism::CallNode node) -> void
87
- def handle_callback ( node )
88
- arguments = node . arguments &.arguments
89
- return unless arguments &.any?
97
+ name = case focus_argument
98
+ when Prism ::SymbolNode
99
+ focus_argument . value
100
+ when Prism ::StringNode
101
+ focus_argument . content
102
+ end
103
+
104
+ return unless name
90
105
91
- arguments . each do |argument |
92
- name = case argument
93
- when Prism ::SymbolNode
94
- argument . value
95
- when Prism ::StringNode
96
- argument . content
97
- end
106
+ collect_definitions ( name )
107
+ end
98
108
99
- next unless name
109
+ #: ((Prism::SymbolNode | Prism::StringNode) node, Prism::CallNode call_node, Array[Prism::Node] arguments) -> void
110
+ def handle_validation ( node , call_node , arguments )
111
+ message = call_node . message
112
+ return unless message
100
113
101
- collect_definitions ( name )
102
- end
114
+ focus_argument = arguments . find { |argument | argument == node }
115
+ return unless focus_argument
116
+
117
+ return unless node . is_a? ( Prism ::SymbolNode )
118
+
119
+ name = node . value
120
+ return unless name
121
+
122
+ # validates_with uses constants, not symbols - skip (handled by constant resolution)
123
+ return if message == "validates_with"
124
+
125
+ collect_definitions ( name )
103
126
end
104
127
105
128
#: (Prism::CallNode node) -> void
@@ -141,6 +164,36 @@ def collect_definitions(name)
141
164
)
142
165
end
143
166
end
167
+
168
+ #: ((Prism::SymbolNode | Prism::StringNode) node, Prism::CallNode call_node, Array[Prism::Node] arguments) -> void
169
+ def handle_if_unless_conditional ( node , call_node , arguments )
170
+ keyword_arguments = arguments . find { |argument | argument . is_a? ( Prism ::KeywordHashNode ) } #: as Prism::KeywordHashNode?
171
+ return unless keyword_arguments
172
+
173
+ element = keyword_arguments . elements . find do |element |
174
+ next false unless element . is_a? ( Prism ::AssocNode )
175
+
176
+ key = element . key
177
+ next false unless key . is_a? ( Prism ::SymbolNode )
178
+
179
+ key_value = key . value
180
+ next false unless key_value == "if" || key_value == "unless"
181
+
182
+ value = element . value
183
+ next false unless value . is_a? ( Prism ::SymbolNode )
184
+
185
+ value == node
186
+ end #: as Prism::AssocNode?
187
+
188
+ return unless element
189
+
190
+ value = element . value #: as Prism::SymbolNode
191
+ method_name = value . value
192
+
193
+ return unless method_name
194
+
195
+ collect_definitions ( method_name )
196
+ end
144
197
end
145
198
end
146
199
end
0 commit comments