Skip to content

Commit

Permalink
Fix inference for compact namespace declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Sep 19, 2024
1 parent 01f51c9 commit 3fa4335
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/ruby_lsp/type_inferrer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,12 @@ def self_receiver_handling(node_context)
return Type.new(node_context.fully_qualified_name) if node_context.surrounding_method

# If we're not inside a method, then we're inside the body of a class or module, which is a singleton
# context
Type.new("#{nesting.join("::")}::<Class:#{nesting.last}>")
# context.
#
# If the class/module definition is using compact style (e.g.: `class Foo::Bar`), then we need to split the name
# into its individual parts to build the correct singleton name
parts = nesting.flat_map { |part| part.split("::") }
Type.new("#{parts.join("::")}::<Class:#{parts.last}>")
end

sig do
Expand Down
34 changes: 34 additions & 0 deletions test/type_inferrer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,40 @@ def test_infer_lambda_literal
assert_equal("Proc", @type_inferrer.infer_receiver_type(node_context).name)
end

def test_infer_self_type_for_compact_namespace
node_context = index_and_locate(<<~RUBY, { line: 1, character: 3 })
class Admin::User
validates
end
RUBY

assert_equal("Admin::User::<Class:User>", @type_inferrer.infer_receiver_type(node_context).name)
end

def test_infer_self_type_for_compact_namespace_inside_method
node_context = index_and_locate(<<~RUBY, { line: 2, character: 4 })
class Admin::User
def foo
hello
end
end
RUBY

assert_equal("Admin::User", @type_inferrer.infer_receiver_type(node_context).name)
end

def test_infer_self_type_for_compact_namespace_inside_singleton_method
node_context = index_and_locate(<<~RUBY, { line: 2, character: 4 })
class Admin::User
def self.foo
hello
end
end
RUBY

assert_equal("Admin::User::<Class:User>", @type_inferrer.infer_receiver_type(node_context).name)
end

private

def index_and_locate(source, position)
Expand Down

0 comments on commit 3fa4335

Please sign in to comment.