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

Add Definition support for routes #331

Merged
merged 2 commits into from
May 1, 2024
Merged

Conversation

andyw8
Copy link
Contributor

@andyw8 andyw8 commented Apr 14, 2024

This PR adds support for the Definition request for Rails routes. This allow jumping from names route, e.g. new_user_path, to the corresponding route declaration, e.g. in routes.rb.

The implementation is based on @tenderlove's prototype in https://github.com/tenderlove/refreshing, and uses the behaviour added by @luanzeba and others in rails/rails#47877.

Notes:

  • For Sorbet projects using the Tapioca DSL generators for routes, the Definition Lookup will return two results - one for the RBI file, and one for the actual route.

  • For Shopify folk: Unfortunately this doesn't work on Core, the source location always point to a super call in routing_annotations.rb. bin/rails routes --expanded has the same problem.

TODO:

  • confirm there is minimal performance impact for apps with a large number of routes
  • verify it doesn't break on older versions of Rails

Testing

It's working well on Identity, (which doesn't use Sorbet) and Code DB (which does use Sorbet).

@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from db49e34 to 740a8a9 Compare April 15, 2024 16:59
@response_builder << Interface::Location.new(
uri: URI::Generic.from_path(path: file_path).to_s,
range: Interface::Range.new(
start: Interface::Position.new(line: Integer(line) - 1, character: 0),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in @tenderlove's prototype he gets the character position by looking for the first non-whitespace character on the line, but I'm not sure it's really necessary.

@andyw8
Copy link
Contributor Author

andyw8 commented Apr 16, 2024

Still a few things to finalize but this is ready for a first round of feedback.

@andyw8 andyw8 marked this pull request as ready for review April 16, 2024 14:23
@andyw8 andyw8 requested a review from a team as a code owner April 16, 2024 14:23
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from ed1bf3c to 6a97d0c Compare April 16, 2024 14:29
@andyw8 andyw8 requested a review from st0012 April 16, 2024 14:34
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from 6a97d0c to 8cb5bcc Compare April 16, 2024 14:37
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from 8cb5bcc to dd36e2a Compare April 16, 2024 14:41
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch 2 times, most recently from 75b69b5 to 23620ab Compare April 16, 2024 18:56
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch 3 times, most recently from 2157fba to e92c3ed Compare April 30, 2024 13:40
@andyw8 andyw8 changed the title WIP: Add Definition support for routes Add Definition support for routes Apr 30, 2024
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from 461e176 to a85afe9 Compare April 30, 2024 15:04
# Older versions of Rails don't support `route_source_locations`.
# We also check it hasn't been disabled.
unless ActionDispatch::Routing::Mapper.respond_to?(:route_source_locations) &&
ActionDispatch::Routing::Mapper.route_source_locations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this check's result be evaluated and stored on the addon-side so we just don't send requests for those older versions of Rails?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 So maybe instead of start returning just { message: "ok" }, it could also return a configuration hash?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I mean we can make the early return in handle_route instead?

We can also use version check instead of respond_to? if we want to avoid pulling Rails components there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't rely purely on the version check because the app could have an initializer which sets route_source_locations to false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for this first iteration I'd like to leave the approach as-is, and we can re-visit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's the case, then ActionDispatch::Routing::Mapper.route_source_locations needs to be in server.rb while ActionDispatch::Routing::Mapper.respond_to?(:route_source_locations) can be on the addon side. This is because only server.rb would be run with the application booted and initializers executed.

However, I also feel like it's not a user-facing option. Otherwise, it'd be accessible via config as well. From the search result, I feel that it's an internal option that's only controlled by Rails environment. If that's true, though, perhaps we don't even check its value as we'd always be running in dev environment anyway? 🤔

@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch 3 times, most recently from cfc7c96 to fb63730 Compare April 30, 2024 18:54
@@ -12,10 +12,8 @@ jobs:
gemfile:
- Gemfile
- gemfiles/Gemfile-rails-main
ruby: ["3.0", "3.1", "3.2", "3.3", "head"]
ruby: ["3.0", "3.1", "3.2", "3.3"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the behaviour added in https://github.com/rails/rails/pull/47877/files is not working properly with Ruby head. Since Rails itself doesn’t test against Ruby head, I think it’s reasonable if we don’t either, and wait until this is fixed upstream.

@andyw8 andyw8 requested a review from vinistock April 30, 2024 19:02
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from fb63730 to e42d059 Compare May 1, 2024 16:02
@andyw8 andyw8 enabled auto-merge (squash) May 1, 2024 16:02
@andyw8 andyw8 disabled auto-merge May 1, 2024 17:12
@andyw8 andyw8 force-pushed the andyw8/jumpt-to-route-definition branch from e42d059 to fca767d Compare May 1, 2024 17:13
@andyw8 andyw8 merged commit c3f6141 into main May 1, 2024
42 checks passed
@andyw8 andyw8 deleted the andyw8/jumpt-to-route-definition branch May 1, 2024 17:45
@andyw8 andyw8 mentioned this pull request May 1, 2024
@andyw8 andyw8 added the enhancement New feature or request label May 3, 2024
@@ -31,7 +31,7 @@ def activate(global_state, message_queue)
@global_state = T.let(global_state, T.nilable(RubyLsp::GlobalState))
$stderr.puts("Activating Ruby LSP Rails addon v#{VERSION}")
# Start booting the real client in a background thread. Until this completes, the client will be a NullClient
Thread.new { @client = RunnerClient.create_client }
Thread.new { @client = RunnerClient.create_client }.join
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(corrected in #356)

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

Successfully merging this pull request may close these issues.

None yet

3 participants