@@ -16,10 +16,12 @@ class DocumentSymbol
1616 def initialize ( response_builder , dispatcher )
1717 @response_builder = response_builder
1818 @namespace_stack = [ ] #: Array[String]
19+ @inside_schema = false #: bool
1920
2021 dispatcher . register (
2122 self ,
2223 :on_call_node_enter ,
24+ :on_call_node_leave ,
2325 :on_class_node_enter ,
2426 :on_class_node_leave ,
2527 :on_module_node_enter ,
@@ -29,6 +31,13 @@ def initialize(response_builder, dispatcher)
2931
3032 #: (Prism::CallNode node) -> void
3133 def on_call_node_enter ( node )
34+ message = node . message
35+ return unless message
36+
37+ @inside_schema = true if node_is_schema_define? ( node )
38+
39+ handle_schema_table ( node )
40+
3241 return if @namespace_stack . empty?
3342
3443 content = extract_test_case_name ( node )
@@ -44,9 +53,6 @@ def on_call_node_enter(node)
4453 receiver = node . receiver
4554 return if receiver && !receiver . is_a? ( Prism ::SelfNode )
4655
47- message = node . message
48- return unless message
49-
5056 case message
5157 when *Support ::Callbacks ::ALL , "validate"
5258 handle_all_arg_types ( node , message )
@@ -58,6 +64,11 @@ def on_call_node_enter(node)
5864 end
5965 end
6066
67+ #: (Prism::CallNode node) -> void
68+ def on_call_node_leave ( node )
69+ @inside_schema = false if node_is_schema_define? ( node )
70+ end
71+
6172 #: (Prism::ClassNode node) -> void
6273 def on_class_node_enter ( node )
6374 add_to_namespace_stack ( node )
@@ -213,6 +224,39 @@ def handle_class_arg_types(node, message)
213224 end
214225 end
215226
227+ #: (Prism::CallNode node) -> void
228+ def handle_schema_table ( node )
229+ return unless @inside_schema
230+ return unless node . message == "create_table"
231+
232+ table_name_argument = node . arguments &.arguments &.first
233+
234+ return unless table_name_argument
235+
236+ case table_name_argument
237+ when Prism ::SymbolNode
238+ name = table_name_argument . value
239+ return unless name
240+
241+ append_document_symbol (
242+ name : name ,
243+ range : range_from_location ( table_name_argument . location ) ,
244+ selection_range : range_from_location (
245+ table_name_argument . value_loc , #: as !nil
246+ ) ,
247+ )
248+ when Prism ::StringNode
249+ name = table_name_argument . content
250+ return if name . empty?
251+
252+ append_document_symbol (
253+ name : name ,
254+ range : range_from_location ( table_name_argument . location ) ,
255+ selection_range : range_from_location ( table_name_argument . content_loc ) ,
256+ )
257+ end
258+ end
259+
216260 #: (name: String, range: RubyLsp::Interface::Range, selection_range: RubyLsp::Interface::Range) -> void
217261 def append_document_symbol ( name :, range :, selection_range :)
218262 @response_builder . last . children << RubyLsp ::Interface ::DocumentSymbol . new (
@@ -222,6 +266,19 @@ def append_document_symbol(name:, range:, selection_range:)
222266 selection_range : selection_range ,
223267 )
224268 end
269+
270+ #: (Prism::CallNode node) -> bool
271+ def node_is_schema_define? ( node )
272+ return false if node . message != "define"
273+
274+ schema_node = node . receiver
275+ return false unless schema_node . is_a? ( Prism ::CallNode )
276+
277+ active_record_node = schema_node . receiver
278+ return false unless active_record_node . is_a? ( Prism ::ConstantPathNode )
279+
280+ constant_name ( active_record_node ) == "ActiveRecord::Schema"
281+ end
225282 end
226283 end
227284end
0 commit comments