ruby-lsp-typeprof 0.3.0 → 0.5.0

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: e970087c448a7fdf79627b8023da3d4172f5882709cfaa22ceebc61d627cae39
4
- data.tar.gz: a2ab61b7d4a2b16db5b3e8d4788b016f92c258a083f1d39b3d697f672678ca86
3
+ metadata.gz: 1b0dc266b02ba9428bd88e6001b094436c17fe94407477e1e2f184825416a40a
4
+ data.tar.gz: 70fa07a521a222f5c9e1ac9a62e2458bd41308b1eb6559a7252d8cfe8298008c
5
5
  SHA512:
6
- metadata.gz: 9b2fc7138694f993b4e80f98fc3496a914cbe4d03ae67bddc5a16ff6792709561a8f51a42d45b0041b3dca45975ef1cb677eb908503c8584334ae603148e2b38
7
- data.tar.gz: 97a2e1aaf9d0e9c6fec4211764dbd26ea5a0e862b3ee3b099e6d863ae48da35e6edbfde577edda4dca8e1b0510221683317f7116ec198f3d22587876e58eb19a
6
+ metadata.gz: 4ed5ddf9b0a88bd9ad17fa748225ad62d23b1ab5e99f181b21a5dea1f10c2fecab850403c39470447487550b11f7a03989b648f7d61aa8ab586b5f8b75d5d50c
7
+ data.tar.gz: 33ea5a60eeb2295adff2ad7f73828d17dabe17cbcc01be64209bca361e8bb8bcd36f61f5b6e84a40601be2e9299817652dae9915024f90a8c6738d1447cdf1c7
data/README.md CHANGED
@@ -27,7 +27,8 @@ Configure them in VS Code's `settings.json`:
27
27
  "rubyLsp.addonSettings": {
28
28
  "TypeProf": {
29
29
  "enabled": false,
30
- "enableCodeLens": false
30
+ "enableCodeLens": false,
31
+ "enableDocumentSymbol": false
31
32
  }
32
33
  }
33
34
  }
@@ -45,6 +46,7 @@ You can place this configuration in either:
45
46
  | --- | --- | --- | --- |
46
47
  | `enabled` | boolean | `true` | Master switch. When `false`, the add-on skips loading TypeProf entirely and disables every feature. |
47
48
  | `enableCodeLens` | boolean | `true` | Show inferred type signatures as code lens above method definitions. Has no effect when `enabled` is `false`. |
49
+ | `enableDocumentSymbol` | boolean | `true` | Add inferred type signatures as child symbols of method definitions in the document symbol response, so clients that do not support code lens (for example Claude Code) can see them. Has no effect when `enabled` is `false`. |
48
50
 
49
51
  After changing the setting, restart Ruby LSP via the "Ruby LSP: Restart"
50
52
  command for it to take effect.
@@ -53,7 +55,9 @@ command for it to take effect.
53
55
 
54
56
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
55
57
 
56
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
58
+ To install this gem onto your local machine, run `bundle exec rake install`.
59
+
60
+ To release a new version, run `bin/bump.rb` (pass `--minor` or `--major` to bump those segments) and push the resulting commit to `main`. The release workflow then publishes the gem to [rubygems.org](https://rubygems.org) and creates a GitHub release.
57
61
 
58
62
  ## Contributing
59
63
 
@@ -5,29 +5,34 @@ require "ruby_lsp/addon"
5
5
  require "uri"
6
6
 
7
7
  require_relative "code_lens_listener"
8
+ require_relative "document_symbol_listener"
9
+ require_relative "loggable"
8
10
 
9
11
  module RubyLsp
10
12
  module Typeprof
11
13
  class Addon < ::RubyLsp::Addon
14
+ include Loggable
15
+
12
16
  def initialize
13
17
  super
14
18
  @service = nil
15
19
  @mutex = Mutex.new
16
20
  @enabled = true
17
21
  @code_lens_enabled = true
22
+ @document_symbol_enabled = true
18
23
  end
19
24
 
20
- def activate(global_state, _outgoing_queue)
21
- settings = global_state.settings_for_addon(name)
22
- @enabled = settings&.dig(:enabled) != false
25
+ def activate(global_state, outgoing_queue)
26
+ @outgoing_queue = outgoing_queue
27
+ log_message("Activating Ruby LSP TypeProf add-on v#{VERSION}")
28
+
29
+ load_settings(global_state)
23
30
  return unless @enabled
24
31
 
25
32
  require "typeprof"
26
-
27
- @code_lens_enabled = settings&.dig(:enableCodeLens) != false
28
33
  @service = build_service(global_state.workspace_path)
29
34
  rescue StandardError => e
30
- warn "ruby-lsp-typeprof: Failed to activate: #{e.message}"
35
+ log_error("Ruby LSP TypeProf failed to activate: #{e.full_message(highlight: false)}")
31
36
  end
32
37
 
33
38
  def deactivate
@@ -46,7 +51,14 @@ module RubyLsp
46
51
  return unless @service
47
52
  return unless @code_lens_enabled
48
53
 
49
- CodeLensListener.new(response_builder, uri, dispatcher, @service, @mutex)
54
+ CodeLensListener.new(response_builder, uri, dispatcher, @service, @mutex, @outgoing_queue)
55
+ end
56
+
57
+ def create_document_symbol_listener(response_builder, dispatcher)
58
+ return unless @service
59
+ return unless @document_symbol_enabled
60
+
61
+ DocumentSymbolListener.new(response_builder, dispatcher, @service, @mutex, @outgoing_queue)
50
62
  end
51
63
 
52
64
  def workspace_did_change_watched_files(changes)
@@ -59,6 +71,13 @@ module RubyLsp
59
71
 
60
72
  private
61
73
 
74
+ def load_settings(global_state)
75
+ settings = global_state.settings_for_addon(name)
76
+ @enabled = settings&.dig(:enabled) != false
77
+ @code_lens_enabled = settings&.dig(:enableCodeLens) != false
78
+ @document_symbol_enabled = settings&.dig(:enableDocumentSymbol) != false
79
+ end
80
+
62
81
  def build_service(workspace_path)
63
82
  conf = load_typeprof_conf(workspace_path) || default_conf
64
83
  rbs_dir = File.expand_path(conf[:rbs_dir], workspace_path)
@@ -92,7 +111,7 @@ module RubyLsp
92
111
 
93
112
  @service.update_file(path, nil)
94
113
  rescue StandardError => e
95
- warn "ruby-lsp-typeprof: Failed to update file #{path}: #{e.message}"
114
+ log_error("Ruby LSP TypeProf failed to update file #{path}: #{e.full_message(highlight: false)}")
96
115
  end
97
116
  end
98
117
  end
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "signature_cache"
4
+
3
5
  module RubyLsp
4
6
  module Typeprof
5
7
  class CodeLensListener
6
- def initialize(response_builder, uri, dispatcher, service, mutex)
8
+ def initialize(response_builder, uri, dispatcher, service, mutex, outgoing_queue)
7
9
  @response_builder = response_builder
8
- @path = uri.to_standardized_path
9
- @lens_cache = {}
10
+ @signatures = SignatureCache.new(service, mutex, uri.to_standardized_path, outgoing_queue, feature: "code lens")
10
11
 
11
- cache_code_lens_results(service, mutex)
12
- dispatcher.register(self, :on_def_node_enter) unless @lens_cache.empty?
12
+ dispatcher.register(self, :on_def_node_enter) unless @signatures.empty?
13
13
  end
14
14
 
15
15
  def on_def_node_enter(node)
16
16
  line = node.location.start_line
17
- hint = @lens_cache[line]
17
+ hint = @signatures[line]
18
18
  return unless hint
19
19
 
20
20
  @response_builder << build_code_lens(line, hint)
@@ -30,16 +30,6 @@ module RubyLsp
30
30
  command: LanguageServer::Protocol::Interface::Command.new(title: "#: #{hint}", command: "")
31
31
  )
32
32
  end
33
-
34
- def cache_code_lens_results(service, mutex)
35
- mutex.synchronize do
36
- service.code_lens(@path) do |code_range, hint|
37
- @lens_cache[code_range.first.lineno] = hint
38
- end
39
- end
40
- rescue StandardError => e
41
- warn "ruby-lsp-typeprof: Code lens error: #{e.message}"
42
- end
43
33
  end
44
34
  end
45
35
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "signature_cache"
4
+
5
+ module RubyLsp
6
+ module Typeprof
7
+ # Appends the inferred method signature as a child symbol of each method
8
+ # definition symbol produced by Ruby LSP's own DocumentSymbol listener.
9
+ #
10
+ # Ruby LSP does not pass the document URI to `create_document_symbol_listener`,
11
+ # so the URI is read from the core listener already registered on the dispatcher.
12
+ class DocumentSymbolListener
13
+ def initialize(response_builder, dispatcher, service, mutex, outgoing_queue)
14
+ @response_builder = response_builder
15
+ path = document_path(dispatcher)
16
+ @signatures = SignatureCache.new(service, mutex, path, outgoing_queue, feature: "document symbol")
17
+
18
+ dispatcher.register(self, :on_def_node_enter) unless @signatures.empty?
19
+ end
20
+
21
+ def on_def_node_enter(node)
22
+ hint = @signatures[node.location.start_line]
23
+ return unless hint
24
+
25
+ parent = @response_builder.last
26
+ return unless parent.is_a?(LanguageServer::Protocol::Interface::DocumentSymbol)
27
+
28
+ parent.children << build_signature_symbol(node, hint)
29
+ end
30
+
31
+ private
32
+
33
+ def document_path(dispatcher)
34
+ core_listener = dispatcher.listeners.each_value.flat_map(&:itself).find do |listener|
35
+ listener.is_a?(::RubyLsp::Listeners::DocumentSymbol)
36
+ end
37
+ core_listener&.instance_variable_get(:@uri)&.to_standardized_path
38
+ end
39
+
40
+ def build_signature_symbol(node, hint)
41
+ range = range_from_location(node.name_loc)
42
+
43
+ LanguageServer::Protocol::Interface::DocumentSymbol.new(
44
+ name: hint,
45
+ kind: ::RubyLsp::Constant::SymbolKind::TYPE_PARAMETER,
46
+ range: range,
47
+ selection_range: range
48
+ )
49
+ end
50
+
51
+ def range_from_location(location)
52
+ LanguageServer::Protocol::Interface::Range.new(
53
+ start: LanguageServer::Protocol::Interface::Position.new(
54
+ line: location.start_line - 1, character: location.start_column
55
+ ),
56
+ end: LanguageServer::Protocol::Interface::Position.new(
57
+ line: location.end_line - 1, character: location.end_column
58
+ )
59
+ )
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module Typeprof
5
+ module Loggable
6
+ private
7
+
8
+ def log_message(message, type: ::RubyLsp::Constant::MessageType::LOG)
9
+ return if @outgoing_queue.nil? || @outgoing_queue.closed?
10
+
11
+ @outgoing_queue << ::RubyLsp::Notification.window_log_message(message, type: type)
12
+ end
13
+
14
+ def log_error(message)
15
+ log_message(message, type: ::RubyLsp::Constant::MessageType::ERROR)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "loggable"
4
+
5
+ module RubyLsp
6
+ module Typeprof
7
+ # Collects the method signatures TypeProf inferred for a single file,
8
+ # keyed by the 1-based line number of the method definition.
9
+ class SignatureCache
10
+ include Loggable
11
+
12
+ def initialize(service, mutex, path, outgoing_queue, feature:)
13
+ @outgoing_queue = outgoing_queue
14
+ @hints = {}
15
+ return unless path
16
+
17
+ mutex.synchronize do
18
+ service.code_lens(path) do |code_range, hint|
19
+ @hints[code_range.first.lineno] = hint
20
+ end
21
+ end
22
+ rescue StandardError => e
23
+ log_error("Ruby LSP TypeProf failed to compute #{feature} for #{path}: #{e.full_message(highlight: false)}")
24
+ end
25
+
26
+ def [](line)
27
+ @hints[line]
28
+ end
29
+
30
+ def empty?
31
+ @hints.empty?
32
+ end
33
+ end
34
+ end
35
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLsp
4
4
  module Typeprof
5
- VERSION = "0.3.0"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-typeprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takumi Shotoku
@@ -44,8 +44,6 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
- - ".tagpr"
48
- - CHANGELOG.md
49
47
  - CODE_OF_CONDUCT.md
50
48
  - LICENSE.txt
51
49
  - README.md
@@ -53,6 +51,9 @@ files:
53
51
  - lib/ruby-lsp-typeprof.rb
54
52
  - lib/ruby_lsp/ruby_lsp_typeprof/addon.rb
55
53
  - lib/ruby_lsp/ruby_lsp_typeprof/code_lens_listener.rb
54
+ - lib/ruby_lsp/ruby_lsp_typeprof/document_symbol_listener.rb
55
+ - lib/ruby_lsp/ruby_lsp_typeprof/loggable.rb
56
+ - lib/ruby_lsp/ruby_lsp_typeprof/signature_cache.rb
56
57
  - lib/ruby_lsp_typeprof/version.rb
57
58
  - sig/ruby_lsp_typeprof/version.rbs
58
59
  homepage: https://github.com/sinsoku/ruby-lsp-typeprof
@@ -60,8 +61,8 @@ licenses:
60
61
  - MIT
61
62
  metadata:
62
63
  homepage_uri: https://github.com/sinsoku/ruby-lsp-typeprof
63
- source_code_uri: https://github.com/sinsoku/ruby-lsp-typeprof/tree/v0.3.0
64
- changelog_uri: https://github.com/sinsoku/ruby-lsp-typeprof/blob/v0.3.0/CHANGELOG.md
64
+ source_code_uri: https://github.com/sinsoku/ruby-lsp-typeprof/tree/v0.5.0
65
+ changelog_uri: https://github.com/sinsoku/ruby-lsp-typeprof/releases
65
66
  rubygems_mfa_required: 'true'
66
67
  rdoc_options: []
67
68
  require_paths:
@@ -77,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
78
  - !ruby/object:Gem::Version
78
79
  version: '0'
79
80
  requirements: []
80
- rubygems_version: 4.0.6
81
+ rubygems_version: 4.0.16
81
82
  specification_version: 4
82
83
  summary: A Ruby LSP addon for TypeProf
83
84
  test_files: []
data/.tagpr DELETED
@@ -1,5 +0,0 @@
1
- [tagpr]
2
- vPrefix = true
3
- releaseBranch = main
4
- versionFile = lib/ruby_lsp_typeprof/version.rb
5
- postVersionCommand = BUNDLE_FROZEN=false bundle install
data/CHANGELOG.md DELETED
@@ -1,11 +0,0 @@
1
- ## [v0.3.0](https://github.com/sinsoku/ruby-lsp-typeprof/compare/v0.2.0...v0.3.0) - 2026-05-08
2
- - feat: Add enabled setting to toggle the entire add-on by @sinsoku in https://github.com/sinsoku/ruby-lsp-typeprof/pull/5
3
-
4
- ## [v0.2.0](https://github.com/sinsoku/ruby-lsp-typeprof/compare/v0.1.1...v0.2.0) - 2026-05-03
5
- - feat: Add enableCodeLens setting via addonSettings by @sinsoku in https://github.com/sinsoku/ruby-lsp-typeprof/pull/4
6
-
7
- ## [v0.1.1](https://github.com/sinsoku/ruby-lsp-typeprof/compare/v0.1.0...v0.1.1) - 2026-04-27
8
-
9
- ## [0.1.0] - 2026-04-27
10
-
11
- - feat: Display type declarations using Code Lens