Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go-to definition for singleton methods defined via class << self #3050

Open
1 task done
jesseduffield opened this issue Jan 11, 2025 · 3 comments
Open
1 task done
Labels
enhancement New feature or request

Comments

@jesseduffield
Copy link

jesseduffield commented Jan 11, 2025

I have checked that this feature is not already implemented

  • This feature does not exist

Use case

I would like to be able to go-to definition for singleton methods defined via the class << self syntax.

Description

Specifically, If I have:

module Foo
  class << self
    def bar
      # do something
    end
  end
end

...
# in another file
Foo.bar

I want to be able to click on the bar in Foo.bar and go to the definition in the Foo module.

Currently you can go to definition for singleton methods defined with the self.foo syntax but not with the class << self syntax.

Implementation

No response

Other

I noticed that there were a couple of PRs relating to this, but they were both closed:
#1113
#1250

@jesseduffield jesseduffield added the enhancement New feature or request label Jan 11, 2025
@vinistock
Copy link
Member

Thank you for the report! We do support that already and I can't reproduce with the example you mentioned. You can verify it in the LSP's codebase too, if you add Addon.load_addons to any file, you can jump to the definition of load_addons and land on the right place.

Those two PRs were closed, but we ended up implementing singleton support in different ones.

I suspect that the problem may be that one of the files in question is being excluded from indexing. Are these test files by any chance? Do you any configuration for indexing?

Note that our defaults exclude test directories from indexing and development gems too.

@jesseduffield
Copy link
Author

Hmm, I've opened the LSP's codebase in vscode and opened the dev container to confirm.

A strange issue I see is that if I hit the keybinding for going to definition when at the end of a word, it doesn't work, but if I'm within the word, then it does work:

ruby-lsp-demo.mov

I've now confirmed in my own codebase that go-to definition works the same, however I've noticed an additional issue: if I have a module that's defined like so:

module Foo::Bar
  class << self
    def baz; end
  end
end

Then if I try to jump to definition for Foo::Bar.baz, it won't work. On the other hand if the module is structured like so:

module Foo
  module Bar
    class << self
      def baz; end
    end
  end
end

It will.

I believe the former syntax is now the preferred approach in rails applications, and I use that approach in my codebase.

@vinistock
Copy link
Member

Thank you for the extra details, that's helpful. Not finding the method inside compact namespaces is an indexing bug, which will be fixed by #3062.

Concerning going to definition in the end of the word, I'll need to do a bit more research to understand what other language servers are doing. When your cursor is at the end of the word, it's position is actually one character after the word, which is why we don't find any targets.

But checking the behaviour on TypeScript, you can indeed jump to definition even if the position is off by one. Maybe the expected implementation is that the server will check if there's any content under the position and if not adjust the position by minus one? I'll need to understand this better.

vinistock added a commit that referenced this issue Jan 14, 2025
### Motivation

Fixes one of the bugs reported in #3050

We were assigning incorrect names to singleton classes defined inside compact namespaces. The issue is that we were simply taking the last entry in the stack, but when using compact namespaces that entry may include multiple names.

### Implementation

Started ensuring we use only the last part of the name to define the singleton.

I also noticed that we were pushing and popping from the name stack when entering a singleton method defined with `def self.foo`. That's actually unnecessary. The name stack is only used for constants and inside a method definition we'll only find instance variables (which use the owner stack rather than the name stack).

I removed the pushing and popping in that case.

### Automated Tests

Added a test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants