Skip to content

Fix type inference for parent scopes and method definitions with receivers#4062

Open
vinistock wants to merge 3 commits intorubydex_adoption_feature_branchfrom
vs_fix_node_context_for_methods_with_receivers
Open

Fix type inference for parent scopes and method definitions with receivers#4062
vinistock wants to merge 3 commits intorubydex_adoption_feature_branchfrom
vs_fix_node_context_for_methods_with_receivers

Conversation

@vinistock
Copy link
Copy Markdown
Member

Motivation

In the original Ruby LSP indexer, we did not handle the resolution of parent scopes used in definitions. For example:

module Bar; end

module Foo
  # This defines `Bar::Baz` because the `Bar` reference gets resolved to top level `Bar`
  # through the lexical scope. Rubydex does this correctly, but the Ruby LSP doesn't
  # run resolution on its node context and misunderstands this as `Foo::Bar::Baz`
  class Bar::Baz
  end
end

Similarly this example

module Foo
  module Bar; end
end

module Baz
  include Foo

  # This doesn't define `Baz::Bar::Qux`. It has access to `Bar` through inheritance
  # and defines `Foo::Bar::Qux`.
  #
  # Note that references to `Baz::Bar::Qux` also work, but not because that's the fully
  # qualified name of the constant. `Baz::Bar` finds `Foo::Bar` through inheritance,
  # allowing you to refer to `Qux`
  class Bar::Qux; end
end

We also did not handle method definition receivers correctly, which don't advance the lexical scope, but modify the type of self. For example:

class Bar; end

class Foo
  def Bar.baz
    # self here is singleton class of Bar (Bar::<Bar>). Therefore, the var reference
    # is accessing `Bar::<Bar>#@var`
    @var
  end
end

Implementation

There are two main parts to fix, which can be found in the first commit:

  1. Started using a new object to represent the surrounding method definition in node context, which includes the receiver
  2. Stopped pushing def self.foo as a singleton entry in the node context nesting. Method receivers don't advance the lexical scope and do not influence constant resolution. They only influence the type of self

Then I made the necessary adjustments on the type inferrer.

Automated Tests

The last commit includes a bunch of tests verifying that we're correctly handling these cases in definition and hover.

@vinistock vinistock self-assigned this Apr 15, 2026
@vinistock vinistock added the bugfix This PR will fix an existing bug label Apr 15, 2026
@vinistock vinistock requested a review from a team as a code owner April 15, 2026 21:35
@vinistock vinistock added the server This pull request should be included in the server gem's release notes label Apr 15, 2026
@vinistock vinistock requested review from alexcrocha and st0012 April 15, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix This PR will fix an existing bug server This pull request should be included in the server gem's release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant