ruby-lsp-rails 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/lib/ruby_lsp/ruby_lsp_rails/addon.rb +8 -6
- data/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb +1 -0
- data/lib/ruby_lsp/ruby_lsp_rails/definition.rb +26 -17
- data/lib/ruby_lsp/ruby_lsp_rails/hover.rb +3 -3
- data/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +16 -0
- data/lib/ruby_lsp/ruby_lsp_rails/server.rb +29 -0
- data/lib/ruby_lsp/ruby_lsp_rails/support/associations.rb +20 -0
- data/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb +33 -0
- data/lib/ruby_lsp_rails/version.rb +1 -1
- metadata +9 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bb6fcc96e3d0fd9357e7f8700acbae09e0d792499ed0d8b92fd577a97949108
|
4
|
+
data.tar.gz: cbb971feed21416f187195d0b23295801dbbc5c875c5d64961f2591e253f375a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc8c684b4900726219d73c2855a1afe159e0ba02f8a953de86356e1cfb9667fe11dff4cbaf3446d5dd471689151f34072f1a099f82033c959516db30dcf81ce7
|
7
|
+
data.tar.gz: 72b8a8ba741fbccd174dc46bb86ef683634630866f209f0968eb6d228992f4986f46bac7f0de249a936649eef80a799c5505f9c8a3514f76d44e77a511b70325
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://join.slack.com/t/ruby-dx/shared_invite/zt-2c8zjlir6-uUDJl8oIwcen_FS_aA~b6Q)
|
2
|
+
|
1
3
|
# Ruby LSP Rails
|
2
4
|
|
3
5
|
Ruby LSP Rails is a [Ruby LSP](https://github.com/Shopify/ruby-lsp) addon for extra Rails editor features, such as:
|
data/Rakefile
CHANGED
@@ -5,7 +5,9 @@ require "ruby_lsp/addon"
|
|
5
5
|
|
6
6
|
require_relative "../../ruby_lsp_rails/version"
|
7
7
|
require_relative "support/active_support_test_case_helper"
|
8
|
+
require_relative "support/associations"
|
8
9
|
require_relative "support/callbacks"
|
10
|
+
require_relative "support/location_builder"
|
9
11
|
require_relative "runner_client"
|
10
12
|
require_relative "hover"
|
11
13
|
require_relative "code_lens"
|
@@ -57,12 +59,12 @@ module RubyLsp
|
|
57
59
|
sig do
|
58
60
|
override.params(
|
59
61
|
response_builder: ResponseBuilders::Hover,
|
60
|
-
|
62
|
+
node_context: NodeContext,
|
61
63
|
dispatcher: Prism::Dispatcher,
|
62
64
|
).void
|
63
65
|
end
|
64
|
-
def create_hover_listener(response_builder,
|
65
|
-
Hover.new(@client, response_builder,
|
66
|
+
def create_hover_listener(response_builder, node_context, dispatcher)
|
67
|
+
Hover.new(@client, response_builder, node_context, T.must(@global_state), dispatcher)
|
66
68
|
end
|
67
69
|
|
68
70
|
sig do
|
@@ -79,13 +81,13 @@ module RubyLsp
|
|
79
81
|
override.params(
|
80
82
|
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
|
81
83
|
uri: URI::Generic,
|
82
|
-
|
84
|
+
node_context: NodeContext,
|
83
85
|
dispatcher: Prism::Dispatcher,
|
84
86
|
).void
|
85
87
|
end
|
86
|
-
def create_definition_listener(response_builder, uri,
|
88
|
+
def create_definition_listener(response_builder, uri, node_context, dispatcher)
|
87
89
|
index = T.must(@global_state).index
|
88
|
-
Definition.new(@client, response_builder,
|
90
|
+
Definition.new(@client, response_builder, node_context, index, dispatcher)
|
89
91
|
end
|
90
92
|
|
91
93
|
sig { params(changes: T::Array[{ uri: String, type: Integer }]).void }
|
@@ -6,6 +6,7 @@ module RubyLsp
|
|
6
6
|
# 
|
7
7
|
#
|
8
8
|
# This feature adds several CodeLens features for Rails applications using Active Support test cases:
|
9
|
+
#
|
9
10
|
# - Run tests in the VS Terminal
|
10
11
|
# - Run tests in the VS Code Test Explorer
|
11
12
|
# - Debug tests
|
@@ -10,6 +10,7 @@ module RubyLsp
|
|
10
10
|
# definition of the symbol under the cursor.
|
11
11
|
#
|
12
12
|
# Currently supported targets:
|
13
|
+
#
|
13
14
|
# - Callbacks
|
14
15
|
# - Named routes (e.g. `users_path`)
|
15
16
|
#
|
@@ -20,6 +21,7 @@ module RubyLsp
|
|
20
21
|
# ```
|
21
22
|
#
|
22
23
|
# Notes for named routes:
|
24
|
+
#
|
23
25
|
# - It is available only in Rails 7.1 or newer.
|
24
26
|
# - Route may be defined across multiple files, e.g. using `draw`, rather than in `routes.rb`.
|
25
27
|
# - Routes won't be found if not defined for the Rails development environment.
|
@@ -33,15 +35,15 @@ module RubyLsp
|
|
33
35
|
params(
|
34
36
|
client: RunnerClient,
|
35
37
|
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
|
36
|
-
|
38
|
+
node_context: NodeContext,
|
37
39
|
index: RubyIndexer::Index,
|
38
40
|
dispatcher: Prism::Dispatcher,
|
39
41
|
).void
|
40
42
|
end
|
41
|
-
def initialize(client, response_builder,
|
43
|
+
def initialize(client, response_builder, node_context, index, dispatcher)
|
42
44
|
@client = client
|
43
45
|
@response_builder = response_builder
|
44
|
-
@nesting = nesting
|
46
|
+
@nesting = T.let(node_context.nesting, T::Array[String])
|
45
47
|
@index = index
|
46
48
|
|
47
49
|
dispatcher.register(self, :on_call_node_enter)
|
@@ -55,7 +57,9 @@ module RubyLsp
|
|
55
57
|
|
56
58
|
return unless message
|
57
59
|
|
58
|
-
if Support::
|
60
|
+
if Support::Associations::ALL.include?(message)
|
61
|
+
handle_association(node)
|
62
|
+
elsif Support::Callbacks::ALL.include?(message)
|
59
63
|
handle_callback(node)
|
60
64
|
elsif message.end_with?("_path") || message.end_with?("_url")
|
61
65
|
handle_route(node)
|
@@ -84,23 +88,28 @@ module RubyLsp
|
|
84
88
|
end
|
85
89
|
|
86
90
|
sig { params(node: Prism::CallNode).void }
|
87
|
-
def
|
88
|
-
|
91
|
+
def handle_association(node)
|
92
|
+
first_argument = node.arguments&.arguments&.first
|
93
|
+
return unless first_argument.is_a?(Prism::SymbolNode)
|
94
|
+
|
95
|
+
association_name = first_argument.unescaped
|
96
|
+
|
97
|
+
result = @client.association_target_location(
|
98
|
+
model_name: @nesting.join("::"),
|
99
|
+
association_name: association_name,
|
100
|
+
)
|
101
|
+
|
89
102
|
return unless result
|
90
103
|
|
91
|
-
|
104
|
+
@response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location))
|
105
|
+
end
|
92
106
|
|
93
|
-
|
94
|
-
|
95
|
-
|
107
|
+
sig { params(node: Prism::CallNode).void }
|
108
|
+
def handle_route(node)
|
109
|
+
result = @client.route_location(T.must(node.message))
|
110
|
+
return unless result
|
96
111
|
|
97
|
-
@response_builder <<
|
98
|
-
uri: URI::Generic.from_path(path: file_path).to_s,
|
99
|
-
range: Interface::Range.new(
|
100
|
-
start: Interface::Position.new(line: Integer(line) - 1, character: 0),
|
101
|
-
end: Interface::Position.new(line: Integer(line) - 1, character: 0),
|
102
|
-
),
|
103
|
-
)
|
112
|
+
@response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location))
|
104
113
|
end
|
105
114
|
|
106
115
|
sig { params(name: String).void }
|
@@ -24,15 +24,15 @@ module RubyLsp
|
|
24
24
|
params(
|
25
25
|
client: RunnerClient,
|
26
26
|
response_builder: ResponseBuilders::Hover,
|
27
|
-
|
27
|
+
node_context: NodeContext,
|
28
28
|
global_state: GlobalState,
|
29
29
|
dispatcher: Prism::Dispatcher,
|
30
30
|
).void
|
31
31
|
end
|
32
|
-
def initialize(client, response_builder,
|
32
|
+
def initialize(client, response_builder, node_context, global_state, dispatcher)
|
33
33
|
@client = client
|
34
34
|
@response_builder = response_builder
|
35
|
-
@nesting = nesting
|
35
|
+
@nesting = T.let(node_context.nesting, T::Array[String])
|
36
36
|
@index = T.let(global_state.index, RubyIndexer::Index)
|
37
37
|
dispatcher.register(self, :on_constant_path_node_enter, :on_constant_read_node_enter, :on_call_node_enter)
|
38
38
|
end
|
@@ -98,6 +98,22 @@ module RubyLsp
|
|
98
98
|
nil
|
99
99
|
end
|
100
100
|
|
101
|
+
sig do
|
102
|
+
params(
|
103
|
+
model_name: String,
|
104
|
+
association_name: String,
|
105
|
+
).returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
106
|
+
end
|
107
|
+
def association_target_location(model_name:, association_name:)
|
108
|
+
make_request(
|
109
|
+
"association_target_location",
|
110
|
+
model_name: model_name,
|
111
|
+
association_name: association_name,
|
112
|
+
)
|
113
|
+
rescue => e
|
114
|
+
$stderr.puts("Ruby LSP Rails failed with #{e.message}: #{@stderr.read}")
|
115
|
+
end
|
116
|
+
|
101
117
|
sig { params(name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
102
118
|
def route_location(name)
|
103
119
|
make_request("route_location", name: name)
|
@@ -20,6 +20,10 @@ module RubyLsp
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def start
|
23
|
+
# Load routes if they haven't been loaded yet (see https://github.com/rails/rails/pull/51614).
|
24
|
+
routes_reloader = ::Rails.application.routes_reloader
|
25
|
+
routes_reloader.execute_unless_loaded if routes_reloader&.respond_to?(:execute_unless_loaded)
|
26
|
+
|
23
27
|
initialize_result = { result: { message: "ok" } }.to_json
|
24
28
|
$stdout.write("Content-Length: #{initialize_result.length}\r\n\r\n#{initialize_result}")
|
25
29
|
|
@@ -43,6 +47,8 @@ module RubyLsp
|
|
43
47
|
VOID
|
44
48
|
when "model"
|
45
49
|
resolve_database_info_from_model(params.fetch(:name))
|
50
|
+
when "association_target_location"
|
51
|
+
resolve_association_target(params)
|
46
52
|
when "reload"
|
47
53
|
::Rails.application.reloader.reload!
|
48
54
|
VOID
|
@@ -110,6 +116,29 @@ module RubyLsp
|
|
110
116
|
{ error: e.full_message(highlight: false) }
|
111
117
|
end
|
112
118
|
|
119
|
+
def resolve_association_target(params)
|
120
|
+
const = ActiveSupport::Inflector.safe_constantize(params[:model_name])
|
121
|
+
unless active_record_model?(const)
|
122
|
+
return {
|
123
|
+
result: nil,
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
association_klass = const.reflect_on_association(params[:association_name].intern).klass
|
128
|
+
|
129
|
+
source_location = Object.const_source_location(association_klass.to_s)
|
130
|
+
|
131
|
+
{
|
132
|
+
result: {
|
133
|
+
location: source_location.first + ":" + source_location.second.to_s,
|
134
|
+
},
|
135
|
+
}
|
136
|
+
rescue NameError
|
137
|
+
{
|
138
|
+
result: nil,
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
113
142
|
def active_record_model?(const)
|
114
143
|
!!(
|
115
144
|
const &&
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Rails
|
6
|
+
module Support
|
7
|
+
module Associations
|
8
|
+
ALL = T.let(
|
9
|
+
[
|
10
|
+
"belongs_to",
|
11
|
+
"has_many",
|
12
|
+
"has_one",
|
13
|
+
"has_and_belongs_to_many",
|
14
|
+
].freeze,
|
15
|
+
T::Array[String],
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Rails
|
6
|
+
module Support
|
7
|
+
class LocationBuilder
|
8
|
+
class << self
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(location_string: String).returns(Interface::Location) }
|
12
|
+
def line_location_from_s(location_string)
|
13
|
+
*file_parts, line = location_string.split(":")
|
14
|
+
|
15
|
+
raise ArgumentError, "Invalid location string given" unless file_parts
|
16
|
+
|
17
|
+
# On Windows, file paths will look something like `C:/path/to/file.rb:123`. Only the last colon is the line
|
18
|
+
# number and all other parts compose the file path
|
19
|
+
file_path = file_parts.join(":")
|
20
|
+
|
21
|
+
Interface::Location.new(
|
22
|
+
uri: URI::Generic.from_path(path: file_path).to_s,
|
23
|
+
range: Interface::Range.new(
|
24
|
+
start: Interface::Position.new(line: Integer(line) - 1, character: 0),
|
25
|
+
end: Interface::Position.new(line: Integer(line) - 1, character: 0),
|
26
|
+
),
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-lsp
|
@@ -16,34 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.17.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.18.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 0.16.5
|
30
|
-
- - "<"
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: 0.17.0
|
33
|
-
-
|
34
|
-
name: sorbet-runtime
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - ">="
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: 0.5.9897
|
40
|
-
type: :runtime
|
41
|
-
prerelease: false
|
42
|
-
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - ">="
|
30
|
+
- - "<"
|
45
31
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.
|
32
|
+
version: 0.18.0
|
47
33
|
description: A Ruby LSP addon that adds extra editor functionality for Rails applications
|
48
34
|
email:
|
49
35
|
- ruby@shopify.com
|
@@ -63,7 +49,9 @@ files:
|
|
63
49
|
- lib/ruby_lsp/ruby_lsp_rails/runner_client.rb
|
64
50
|
- lib/ruby_lsp/ruby_lsp_rails/server.rb
|
65
51
|
- lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb
|
52
|
+
- lib/ruby_lsp/ruby_lsp_rails/support/associations.rb
|
66
53
|
- lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb
|
54
|
+
- lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb
|
67
55
|
- lib/ruby_lsp/ruby_lsp_rails/support/rails_document_client.rb
|
68
56
|
- lib/ruby_lsp_rails/railtie.rb
|
69
57
|
- lib/ruby_lsp_rails/version.rb
|
@@ -91,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
79
|
- !ruby/object:Gem::Version
|
92
80
|
version: '0'
|
93
81
|
requirements: []
|
94
|
-
rubygems_version: 3.5.
|
82
|
+
rubygems_version: 3.5.10
|
95
83
|
signing_key:
|
96
84
|
specification_version: 4
|
97
85
|
summary: A Ruby LSP addon for Rails
|