Skip to content

Commit 0a0ca96

Browse files
committed
Add RBS type definition file jump to typeDefinition LSP feature
Previously, typeDefinition only jumped to Ruby class/module definitions. This change enables jumping to RBS declaration files from: - Class/module constants (e.g., Foo in Foo.new) - Local variables and instance variables holding class instances Also adds tests for both scenarios.
1 parent 14ffbcf commit 0a0ca96

5 files changed

Lines changed: 98 additions & 5 deletions

File tree

lib/typeprof/core/service.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,20 @@ def type_definitions(path, pos)
203203
if node.ret
204204
ty_defs = []
205205
node.ret.types.map do |ty, _source|
206-
if ty.is_a?(Type::Instance)
207-
ty.mod.module_decls.each do |mdecl|
208-
# TODO
206+
mod = case ty
207+
when Type::Instance, Type::Singleton
208+
ty.mod
209+
else
210+
base = ty.base_type(@genv)
211+
base.mod if base.is_a?(Type::Instance)
212+
end
213+
214+
if mod
215+
mod.module_decls.each do |mdecl|
216+
decl_path = mdecl.lenv.path
217+
ty_defs << [decl_path, mdecl.code_range] if decl_path
209218
end
210-
ty.mod.module_defs.each do |mdef_node|
219+
mod.module_defs.each do |mdef_node|
211220
ty_defs << [mdef_node.lenv.path, mdef_node.code_range]
212221
end
213222
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Foo
2+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Foo
2+
end
3+
4+
foo = Foo.new
5+
foo
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"typeprof_version": "experimental",
3+
"analysis_unit_dirs": ["."],
4+
"sig_dirs": ["sig"]
5+
}

test/lsp/lsp_test.rb

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,78 @@ def test(x)
285285
end
286286
end
287287

288-
# TODO: add a test for definition (for crossing files)
288+
def test_type_definition_for_class_constant
289+
init("type_definition")
290+
291+
notify(
292+
"textDocument/didOpen",
293+
textDocument: { uri: @folder + "test.rb", version: 0, text: <<-END },
294+
class Foo
295+
end
296+
297+
foo = Foo.new
298+
foo
299+
END
300+
)
301+
302+
expect_notification("typeprof.enableToggleButton") {|json| }
303+
expect_request("workspace/codeLens/refresh") {|json| }
304+
305+
id = request(
306+
"textDocument/typeDefinition",
307+
textDocument: { uri: @folder + "test.rb" },
308+
position: { line: 3, character: 6 },
309+
)
310+
311+
expect_response(id) do |json|
312+
assert_equal(2, json.size)
313+
314+
rbs_result = json.find { |r| r[:uri].end_with?(".rbs") }
315+
rb_result = json.find { |r| r[:uri].end_with?(".rb") }
316+
317+
assert_not_nil(rbs_result, "RBS definition should be found")
318+
assert_not_nil(rb_result, "Ruby definition should be found")
319+
320+
assert(rbs_result[:uri].end_with?("sig/test.rbs"))
321+
assert(rb_result[:uri].end_with?("test.rb"))
322+
end
323+
end
324+
325+
def test_type_definition_for_local_variable
326+
init("type_definition")
327+
328+
notify(
329+
"textDocument/didOpen",
330+
textDocument: { uri: @folder + "test.rb", version: 0, text: <<-END },
331+
class Foo
332+
end
333+
334+
foo = Foo.new
335+
foo
336+
END
337+
)
338+
339+
expect_notification("typeprof.enableToggleButton") {|json| }
340+
expect_request("workspace/codeLens/refresh") {|json| }
341+
342+
id = request(
343+
"textDocument/typeDefinition",
344+
textDocument: { uri: @folder + "test.rb" },
345+
position: { line: 4, character: 0 },
346+
)
347+
348+
expect_response(id) do |json|
349+
assert_equal(2, json.size)
350+
351+
rbs_result = json.find { |r| r[:uri].end_with?(".rbs") }
352+
rb_result = json.find { |r| r[:uri].end_with?(".rb") }
353+
354+
assert_not_nil(rbs_result, "RBS definition should be found")
355+
assert_not_nil(rb_result, "Ruby definition should be found")
356+
357+
assert(rbs_result[:uri].end_with?("sig/test.rbs"))
358+
assert(rb_result[:uri].end_with?("test.rb"))
359+
end
360+
end
289361
end
290362
end

0 commit comments

Comments
 (0)