Skip to content

Commit ffd73e7

Browse files
Don't add symbol unless in a class/module
1 parent 510342c commit ffd73e7

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@ class DocumentSymbol
2121
end
2222
def initialize(response_builder, dispatcher)
2323
@response_builder = response_builder
24-
25-
dispatcher.register(self, :on_call_node_enter)
24+
@namespace_stack = T.let([], T::Array[String])
25+
26+
dispatcher.register(
27+
self,
28+
:on_call_node_enter,
29+
:on_class_node_enter,
30+
:on_class_node_leave,
31+
:on_module_node_enter,
32+
:on_module_node_leave,
33+
)
2634
end
2735

2836
sig { params(node: Prism::CallNode).void }
@@ -37,6 +45,8 @@ def on_call_node_enter(node)
3745
)
3846
end
3947

48+
return if @namespace_stack.empty?
49+
4050
receiver = node.receiver
4151
return if receiver && !receiver.is_a?(Prism::SelfNode)
4252

@@ -52,8 +62,38 @@ def on_call_node_enter(node)
5262
end
5363
end
5464

65+
sig { params(node: Prism::ClassNode).void }
66+
def on_class_node_enter(node)
67+
add_to_namespace_stack(node)
68+
end
69+
70+
sig { params(node: Prism::ClassNode).void }
71+
def on_class_node_leave(node)
72+
remove_from_namespace_stack(node)
73+
end
74+
75+
sig { params(node: Prism::ModuleNode).void }
76+
def on_module_node_enter(node)
77+
add_to_namespace_stack(node)
78+
end
79+
80+
sig { params(node: Prism::ModuleNode).void }
81+
def on_module_node_leave(node)
82+
remove_from_namespace_stack(node)
83+
end
84+
5585
private
5686

87+
sig { params(node: T.any(Prism::ClassNode, Prism::ModuleNode)).void }
88+
def add_to_namespace_stack(node)
89+
@namespace_stack << node.constant_path.slice
90+
end
91+
92+
sig { params(node: T.any(Prism::ClassNode, Prism::ModuleNode)).void }
93+
def remove_from_namespace_stack(node)
94+
@namespace_stack.delete(node.constant_path.slice)
95+
end
96+
5797
sig { params(node: Prism::CallNode, message: String).void }
5898
def handle_all_arg_types(node, message)
5999
block = node.block

test/ruby_lsp_rails/document_symbol_test.rb

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class FooModel < ApplicationRecord
168168
assert_equal("attr_readonly :foo", response[0].children[0].name)
169169
end
170170

171-
test "correctly handles scope" do
171+
test "correctly handles scope in a class" do
172172
response = generate_document_symbols_for_source(<<~RUBY)
173173
class FooModel < ApplicationRecord
174174
scope :bar, ->{ where(b: 2).order(:c) }
@@ -183,6 +183,37 @@ class FooModel < ApplicationRecord
183183
assert_equal("scope :foo", response[0].children[1].name)
184184
end
185185

186+
test "correctly handles scope in a concern" do
187+
response = generate_document_symbols_for_source(<<~RUBY)
188+
module Scopable
189+
extend ActiveSupport::Concern
190+
191+
included do
192+
scope :bar, ->{ where(b: 2).order(:c) }
193+
scope :foo, ->{ where(a: 1).order(:b) }
194+
end
195+
end
196+
RUBY
197+
198+
assert_equal(1, response.size)
199+
assert_equal("Scopable", response[0].name)
200+
assert_equal(2, response[0].children.size)
201+
assert_equal("scope :bar", response[0].children[0].name)
202+
assert_equal("scope :foo", response[0].children[1].name)
203+
end
204+
205+
test "ignores scope in a routes file" do
206+
response = generate_document_symbols_for_source(<<~RUBY)
207+
Rails.application.routes.draw do
208+
scope '/admin' do
209+
resources :users
210+
end
211+
end
212+
RUBY
213+
214+
assert_equal(0, response.size)
215+
end
216+
186217
test "correctly handles model callbacks with multiple string arguments" do
187218
response = generate_document_symbols_for_source(<<~RUBY)
188219
class FooModel < ApplicationRecord

0 commit comments

Comments
 (0)