Skip to content

Commit 97d4519

Browse files
committed
wip
1 parent 823e68d commit 97d4519

File tree

6 files changed

+72
-33
lines changed

6 files changed

+72
-33
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Ruby LSP Rails is a [Ruby LSP](https://github.com/Shopify/ruby-lsp) addon for ex
66
* Run or debug a test by clicking on the code lens which appears above the test class, or an individual test.
77
* Navigate to associations, validations, callbacks and test cases using your editor's "Go to Symbol" feature, or outline view.
88
* Jump to the definition of callbacks using your editor's "Go to Definition" feature.
9+
* Jump to the definition of a route.
910

1011
## Installation
1112

lib/ruby_lsp/ruby_lsp_rails/definition.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@ module Rails
1111
#
1212
# Currently supported targets:
1313
# - Callbacks
14+
# - Routes
1415
#
1516
# # Example
1617
#
1718
# ```ruby
1819
# before_action :foo # <- Go to definition on this symbol will jump to the method if it is defined in the same class
1920
# ```
20-
# Works even if multiple files, e.g.:
21+
#
22+
# Works even if the routes are defined in multiple files, e.g.:
23+
#
24+
# # route.rb
25+
#
2126
# Rails.application.routes.draw do
22-
# load 'config/routes/oauth.rb'
27+
# load "config/routes/oauth.rb"
2328
# end
29+
#
2430
# Won't work if route is not defined for in the development Rails env.
25-
# Works for users_path() but not users_path, trying to figure out why.
26-
# TODO: handle case for route_source_locations being false
2731
class Definition
2832
extend T::Sig
2933
include Requests::Support::Common
@@ -61,6 +65,8 @@ def on_call_node_enter(node)
6165
end
6266
end
6367

68+
private
69+
6470
sig { params(node: Prism::CallNode).void }
6571
def handle_callback(node)
6672
arguments = node.arguments&.arguments
@@ -99,8 +105,6 @@ def handle_route(node)
99105
)
100106
end
101107

102-
private
103-
104108
sig { params(name: String).void }
105109
def collect_definitions(name)
106110
methods = @index.resolve_method(name, @nesting.join("::"))

lib/ruby_lsp/ruby_lsp_rails/runner_client.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ def initialize
7474

7575
$stderr.puts("Finished booting Ruby LSP Rails server")
7676

77+
unless ActionDispatch::Routing::Mapper.route_source_locations
78+
$stderr.puts("Warning: `route_source_locations` is not enabled in the Rails application. Some features will be unavailable.")
79+
end
80+
7781
unless ENV["RAILS_ENV"] == "test"
7882
at_exit do
7983
if @wait_thread.alive?

lib/ruby_lsp/ruby_lsp_rails/server.rb

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
# NOTE: We should avoid printing to stderr since it causes problems. We never read the standard error pipe from the
2323
# client, so it will become full and eventually hang or crash. Instead, return a response with an `error` key.
2424

25-
ActionDispatch::Routing::Mapper.route_source_locations = true
25+
# ActionDispatch::Routing::Mapper.route_source_locations = true
2626

2727
module RubyLsp
2828
module Rails
@@ -73,30 +73,7 @@ def execute(request, params)
7373
::Rails.application.reloader.reload!
7474
VOID
7575
when "route_location"
76-
unless ActionDispatch::Routing::Mapper.route_source_locations
77-
return { error: "ABC" }
78-
end
79-
80-
$stderr.puts("***params: #{params}")
81-
name = T.must(params).fetch(:name).match(/^([a-z_]+)(_path|_url)$/)[1]
82-
83-
unless name
84-
raise "no name found in: #{params}"
85-
end
86-
87-
unless ::Rails.application.routes.named_routes.key?(name)
88-
return {
89-
result: {
90-
location: nil,
91-
},
92-
}
93-
end
94-
95-
{
96-
result: {
97-
location: ::Rails.root.to_s + "/" + ::Rails.application.routes.named_routes.get(name).source_location,
98-
},
99-
}
76+
route_location(T.must(params).fetch(:name))
10077
else
10178
VOID
10279
end
@@ -106,6 +83,42 @@ def execute(request, params)
10683

10784
private
10885

86+
sig { params(name: String).returns(T::Hash[Symbol, T.untyped]) }
87+
def route_location(name)
88+
unless ActionDispatch::Routing::Mapper.route_source_locations
89+
return {
90+
result: {
91+
location: nil,
92+
},
93+
}
94+
end
95+
96+
key = name.match(/^([a-z_]+)(_path|_url)$/)[1]
97+
98+
unless ::Rails.application.routes.named_routes.key?(key)
99+
return {
100+
result: {
101+
location: nil,
102+
},
103+
}
104+
end
105+
106+
route = ::Rails.application.routes.named_routes.get(key)
107+
108+
unless route&.source_location
109+
return {
110+
result: {
111+
location: nil,
112+
},
113+
}
114+
end
115+
{
116+
result: {
117+
location: ::Rails.root.to_s + "/" + route.source_location,
118+
},
119+
}
120+
end
121+
109122
sig { params(model_name: String).returns(T::Hash[Symbol, T.untyped]) }
110123
def resolve_database_info_from_model(model_name)
111124
const = ActiveSupport::Inflector.safe_constantize(model_name)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# typed: true
22
# frozen_string_literal: true
33

4-
# Route source locations are normally only available in development, so we need to enable them in test mode.
4+
# Route source locations are normally only available in development, so we need to enable this in test mode.
55
ActionDispatch::Routing::Mapper.route_source_locations = true

test/ruby_lsp_rails/definition_test.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,24 @@ def baz; end
111111
invalid_path
112112
RUBY
113113

114-
assert_equal(0, response.size)
114+
assert_empty(response)
115+
end
116+
117+
test "returns an empty response if `route_source_locations` isn't enabled" do
118+
FileUtils.mv(
119+
"test/dummy/config/initializers/action_dispatch.rb",
120+
"test/dummy/config/initializers/action_dispatch.rb.bak",
121+
)
122+
response = generate_definitions_for_source(<<~RUBY, { line: 0, character: 0 })
123+
users_path
124+
RUBY
125+
126+
assert_empty(response)
127+
ensure
128+
FileUtils.mv(
129+
"test/dummy/config/initializers/action_dispatch.rb.bak",
130+
"test/dummy/config/initializers/action_dispatch.rb",
131+
)
115132
end
116133

117134
private

0 commit comments

Comments
 (0)