ruby-lsp-rails 0.3.11 → 0.3.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e684ecacd45b09fee18e386a95d0dfa61bd3cce2c64869bf34f711d9d0c2fa3
4
- data.tar.gz: c575d062c88f997967989f1cca84a1241fb6d07750a0535e122112b890e9dd0e
3
+ metadata.gz: e2543aa7d39f0a6b231112f9ddb365692c7e8d06eb14681da551ab55fd8f5a4d
4
+ data.tar.gz: e466ccd6d90934e083e638efdcedfb5d6b8f85fbce70b139e1542eeb2ab8a139
5
5
  SHA512:
6
- metadata.gz: 17c1805f2e1d7363e2734d6983fdba8b11b72e083ff07b0d872745121f9b4c1d20898e439a19c7dc9f179f8729260cf2f90e701e47967d4901576166fe66c420
7
- data.tar.gz: '039f940ff0ea3247316609b379396a7096ada44ed0b4127969223c3277d946bbbd913e106ede27912fc29c53a0e349999231e1561940e5d75ff6adbf0cea1a89'
6
+ metadata.gz: 8f7c82462682d93fd6b944c2705c8b62b424b4abc3636d1f2540eeee1ab9f7e2896eb77d338697bb65a0a64752529085f38e49bd5a75bfc668fa9d31dd5b0d10
7
+ data.tar.gz: a8978fdebb07ba8b76dd10a725b3b3c736961f103cefa806fbc0302b494516e0a196105bf7fac9d114c963a62c8a706959d53f1509a4ed343e2e9d24633c4372
@@ -13,6 +13,7 @@ require_relative "hover"
13
13
  require_relative "code_lens"
14
14
  require_relative "document_symbol"
15
15
  require_relative "definition"
16
+ require_relative "indexing_enhancement"
16
17
 
17
18
  module RubyLsp
18
19
  module Rails
@@ -35,6 +36,8 @@ module RubyLsp
35
36
  # Start booting the real client in a background thread. Until this completes, the client will be a NullClient
36
37
  Thread.new { @client = RunnerClient.create_client }
37
38
  register_additional_file_watchers(global_state: global_state, message_queue: message_queue)
39
+
40
+ T.must(@global_state).index.register_enhancement(IndexingEnhancement.new)
38
41
  end
39
42
 
40
43
  sig { override.void }
@@ -77,7 +80,9 @@ module RubyLsp
77
80
 
78
81
  sig do
79
82
  override.params(
80
- response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
83
+ response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
84
+ Interface::Location, Interface::LocationLink
85
+ )],
81
86
  uri: URI::Generic,
82
87
  node_context: NodeContext,
83
88
  dispatcher: Prism::Dispatcher,
@@ -51,7 +51,7 @@ module RubyLsp
51
51
  # class AddFirstNameToUsers < ActiveRecord::Migration[7.1]
52
52
  # # ...
53
53
  # end
54
- # ````
54
+ # ```
55
55
  #
56
56
  # The code lenses will be displayed above the class and above each test method.
57
57
  #
@@ -17,7 +17,7 @@ module RubyLsp
17
17
  # # Example
18
18
  #
19
19
  # ```ruby
20
- # before_action :foo # <- Go to definition on this symbol will jump to the method if it is defined in the same class
20
+ # before_action :foo # <- Go to definition on this symbol will jump to the method
21
21
  # ```
22
22
  #
23
23
  # Notes for named routes:
@@ -34,7 +34,9 @@ module RubyLsp
34
34
  sig do
35
35
  params(
36
36
  client: RunnerClient,
37
- response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
37
+ response_builder: RubyLsp::ResponseBuilders::CollectionResponseBuilder[T.any(
38
+ Interface::Location, Interface::LocationLink
39
+ )],
38
40
  node_context: NodeContext,
39
41
  index: RubyIndexer::Index,
40
42
  dispatcher: Prism::Dispatcher,
@@ -0,0 +1,113 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Rails
6
+ class IndexingEnhancement
7
+ extend T::Sig
8
+ include RubyIndexer::Enhancement
9
+
10
+ sig do
11
+ override.params(
12
+ index: RubyIndexer::Index,
13
+ owner: T.nilable(RubyIndexer::Entry::Namespace),
14
+ node: Prism::CallNode,
15
+ file_path: String,
16
+ ).void
17
+ end
18
+ def on_call_node(index, owner, node, file_path)
19
+ return unless owner
20
+
21
+ name = node.name
22
+
23
+ case name
24
+ when :extend
25
+ handle_concern_extend(index, owner, node)
26
+ when :has_one, :has_many, :belongs_to, :has_and_belongs_to_many
27
+ handle_association(index, owner, node, file_path)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ sig do
34
+ params(
35
+ index: RubyIndexer::Index,
36
+ owner: RubyIndexer::Entry::Namespace,
37
+ node: Prism::CallNode,
38
+ file_path: String,
39
+ ).void
40
+ end
41
+ def handle_association(index, owner, node, file_path)
42
+ arguments = node.arguments&.arguments
43
+ return unless arguments
44
+
45
+ name_arg = arguments.first
46
+
47
+ name = case name_arg
48
+ when Prism::StringNode
49
+ name_arg.content
50
+ when Prism::SymbolNode
51
+ name_arg.value
52
+ end
53
+
54
+ return unless name
55
+
56
+ # Reader
57
+ index.add(RubyIndexer::Entry::Method.new(
58
+ name,
59
+ file_path,
60
+ name_arg.location,
61
+ name_arg.location,
62
+ [],
63
+ [RubyIndexer::Entry::Signature.new([])],
64
+ RubyIndexer::Entry::Visibility::PUBLIC,
65
+ owner,
66
+ ))
67
+
68
+ # Writer
69
+ index.add(RubyIndexer::Entry::Method.new(
70
+ "#{name}=",
71
+ file_path,
72
+ name_arg.location,
73
+ name_arg.location,
74
+ [],
75
+ [RubyIndexer::Entry::Signature.new([RubyIndexer::Entry::RequiredParameter.new(name: name.to_sym)])],
76
+ RubyIndexer::Entry::Visibility::PUBLIC,
77
+ owner,
78
+ ))
79
+ end
80
+
81
+ sig do
82
+ params(
83
+ index: RubyIndexer::Index,
84
+ owner: RubyIndexer::Entry::Namespace,
85
+ node: Prism::CallNode,
86
+ ).void
87
+ end
88
+ def handle_concern_extend(index, owner, node)
89
+ arguments = node.arguments&.arguments
90
+ return unless arguments
91
+
92
+ arguments.each do |node|
93
+ next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
94
+
95
+ module_name = node.full_name
96
+ next unless module_name == "ActiveSupport::Concern"
97
+
98
+ index.register_included_hook(owner.name) do |index, base|
99
+ class_methods_name = "#{owner.name}::ClassMethods"
100
+
101
+ if index.indexed?(class_methods_name)
102
+ singleton = index.existing_or_new_singleton_class(base.name)
103
+ singleton.mixin_operations << RubyIndexer::Entry::Include.new(class_methods_name)
104
+ end
105
+ end
106
+ rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
107
+ Prism::ConstantPathNode::MissingNodesInConstantPathError
108
+ # Do nothing
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -41,6 +41,7 @@ module RubyLsp
41
41
 
42
42
  sig { void }
43
43
  def initialize
44
+ @mutex = T.let(Mutex.new, Mutex)
44
45
  # Spring needs a Process session ID. It uses this ID to "attach" itself to the parent process, so that when the
45
46
  # parent ends, the spring process ends as well. If this is not set, Spring will throw an error while trying to
46
47
  # set its own session ID
@@ -84,9 +85,7 @@ module RubyLsp
84
85
  if @wait_thread.alive?
85
86
  $stderr.puts("Ruby LSP Rails is force killing the server")
86
87
  sleep(0.5) # give the server a bit of time if we already issued a shutdown notification
87
-
88
- # Windows does not support the `TERM` signal, so we're forced to use `KILL` here
89
- Process.kill(T.must(Signal.list["KILL"]), @wait_thread.pid)
88
+ force_kill
90
89
  end
91
90
  end
92
91
  end
@@ -149,6 +148,9 @@ module RubyLsp
149
148
  send_message("shutdown")
150
149
  sleep(0.5) # give the server a bit of time to shutdown
151
150
  [@stdin, @stdout, @stderr].each(&:close)
151
+ rescue IOError
152
+ # The server connection may have died
153
+ force_kill
152
154
  end
153
155
 
154
156
  sig { returns(T::Boolean) }
@@ -169,28 +171,35 @@ module RubyLsp
169
171
  read_response
170
172
  end
171
173
 
172
- sig { params(request: String, params: T.nilable(T::Hash[Symbol, T.untyped])).void }
174
+ sig { overridable.params(request: String, params: T.nilable(T::Hash[Symbol, T.untyped])).void }
173
175
  def send_message(request, params = nil)
174
176
  message = { method: request }
175
177
  message[:params] = params if params
176
178
  json = message.to_json
177
179
 
178
- @stdin.write("Content-Length: #{json.length}\r\n\r\n", json)
180
+ @mutex.synchronize do
181
+ @stdin.write("Content-Length: #{json.length}\r\n\r\n", json)
182
+ end
179
183
  rescue Errno::EPIPE
180
184
  # The server connection died
181
185
  end
182
186
 
183
- alias_method :send_notification, :send_message
187
+ # Notifications are like messages, but one-way, with no response sent back.
188
+ sig { params(request: String, params: T.nilable(T::Hash[Symbol, T.untyped])).void }
189
+ def send_notification(request, params = nil) = send_message(request, params)
184
190
 
185
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
191
+ sig { overridable.returns(T.nilable(T::Hash[Symbol, T.untyped])) }
186
192
  def read_response
187
- headers = @stdout.gets("\r\n\r\n")
188
- raise IncompleteMessageError unless headers
193
+ raw_response = @mutex.synchronize do
194
+ headers = @stdout.gets("\r\n\r\n")
195
+ raise IncompleteMessageError unless headers
189
196
 
190
- content_length = headers[/Content-Length: (\d+)/i, 1].to_i
191
- raise EmptyMessageError if content_length.zero?
197
+ content_length = headers[/Content-Length: (\d+)/i, 1].to_i
198
+ raise EmptyMessageError if content_length.zero?
199
+
200
+ @stdout.read(content_length)
201
+ end
192
202
 
193
- raw_response = @stdout.read(content_length)
194
203
  response = JSON.parse(T.must(raw_response), symbolize_names: true)
195
204
 
196
205
  if response[:error]
@@ -203,6 +212,12 @@ module RubyLsp
203
212
  # The server connection died
204
213
  nil
205
214
  end
215
+
216
+ sig { void }
217
+ def force_kill
218
+ # Windows does not support the `TERM` signal, so we're forced to use `KILL` here
219
+ Process.kill(T.must(Signal.list["KILL"]), @wait_thread.pid)
220
+ end
206
221
  end
207
222
 
208
223
  class NullClient < RunnerClient
@@ -3,6 +3,6 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Rails
6
- VERSION = "0.3.11"
6
+ VERSION = "0.3.13"
7
7
  end
8
8
  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.11
4
+ version: 0.3.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-19 00:00:00.000000000 Z
11
+ date: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-lsp
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.17.2
19
+ version: 0.17.12
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.18.0
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.17.2
29
+ version: 0.17.12
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.18.0
@@ -46,6 +46,7 @@ files:
46
46
  - lib/ruby_lsp/ruby_lsp_rails/definition.rb
47
47
  - lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb
48
48
  - lib/ruby_lsp/ruby_lsp_rails/hover.rb
49
+ - lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb
49
50
  - lib/ruby_lsp/ruby_lsp_rails/runner_client.rb
50
51
  - lib/ruby_lsp/ruby_lsp_rails/server.rb
51
52
  - lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb
@@ -79,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
80
  - !ruby/object:Gem::Version
80
81
  version: '0'
81
82
  requirements: []
82
- rubygems_version: 3.5.15
83
+ rubygems_version: 3.5.17
83
84
  signing_key:
84
85
  specification_version: 4
85
86
  summary: A Ruby LSP addon for Rails