ruby-lsp 0.23.11 → 0.23.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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp-launcher +12 -11
  5. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
  6. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
  7. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
  8. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
  9. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
  10. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +88 -200
  11. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +56 -192
  12. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  13. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
  14. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
  15. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
  16. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
  17. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
  18. data/lib/ruby_indexer/test/configuration_test.rb +42 -3
  19. data/lib/ruby_indexer/test/method_test.rb +28 -2
  20. data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
  21. data/lib/ruby_lsp/addon.rb +44 -71
  22. data/lib/ruby_lsp/base_server.rb +29 -32
  23. data/lib/ruby_lsp/client_capabilities.rb +10 -12
  24. data/lib/ruby_lsp/document.rb +34 -45
  25. data/lib/ruby_lsp/erb_document.rb +24 -36
  26. data/lib/ruby_lsp/global_state.rb +51 -56
  27. data/lib/ruby_lsp/internal.rb +2 -0
  28. data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
  29. data/lib/ruby_lsp/listeners/completion.rb +36 -55
  30. data/lib/ruby_lsp/listeners/definition.rb +37 -51
  31. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  32. data/lib/ruby_lsp/listeners/document_link.rb +43 -62
  33. data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
  34. data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
  35. data/lib/ruby_lsp/listeners/hover.rb +81 -100
  36. data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
  37. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
  38. data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
  39. data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
  40. data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
  41. data/lib/ruby_lsp/listeners/test_style.rb +160 -88
  42. data/lib/ruby_lsp/node_context.rb +12 -39
  43. data/lib/ruby_lsp/rbs_document.rb +8 -6
  44. data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
  45. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  46. data/lib/ruby_lsp/requests/code_lens.rb +6 -17
  47. data/lib/ruby_lsp/requests/completion.rb +7 -20
  48. data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
  49. data/lib/ruby_lsp/requests/definition.rb +8 -17
  50. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  51. data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
  52. data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
  53. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  54. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  55. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  56. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  57. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
  58. data/lib/ruby_lsp/requests/hover.rb +8 -18
  59. data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
  60. data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
  61. data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
  62. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
  63. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  64. data/lib/ruby_lsp/requests/references.rb +6 -36
  65. data/lib/ruby_lsp/requests/rename.rb +11 -37
  66. data/lib/ruby_lsp/requests/request.rb +7 -19
  67. data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
  68. data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
  69. data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
  70. data/lib/ruby_lsp/requests/signature_help.rb +8 -26
  71. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  72. data/lib/ruby_lsp/requests/support/common.rb +13 -50
  73. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  74. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
  75. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
  76. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  77. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  78. data/lib/ruby_lsp/requests/support/source_uri.rb +16 -30
  79. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  80. data/lib/ruby_lsp/requests/support/test_item.rb +10 -14
  81. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  82. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  83. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
  84. data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
  85. data/lib/ruby_lsp/response_builders/hover.rb +10 -13
  86. data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
  87. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
  88. data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
  89. data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
  90. data/lib/ruby_lsp/ruby_document.rb +22 -60
  91. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
  92. data/lib/ruby_lsp/scope.rb +7 -11
  93. data/lib/ruby_lsp/server.rb +133 -74
  94. data/lib/ruby_lsp/setup_bundler.rb +58 -57
  95. data/lib/ruby_lsp/static_docs.rb +4 -7
  96. data/lib/ruby_lsp/store.rb +21 -40
  97. data/lib/ruby_lsp/test_helper.rb +3 -12
  98. data/lib/ruby_lsp/test_reporter.rb +207 -0
  99. data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
  100. data/lib/ruby_lsp/type_inferrer.rb +9 -13
  101. data/lib/ruby_lsp/utils.rb +37 -81
  102. metadata +9 -3
@@ -3,93 +3,180 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Listeners
6
- class TestStyle
7
- extend T::Sig
6
+ class TestStyle < TestDiscovery
7
+ class << self
8
+ # Resolves the minimal set of commands required to execute the requested tests
9
+ #: (Array[Hash[Symbol, untyped]]) -> Array[String]
10
+ def resolve_test_commands(items)
11
+ # A nested hash of file_path => test_group => { tags: [], examples: [test_example] } to ensure we build the
12
+ # minimum amount of commands needed to execute the requested tests. This is only used for specific examples
13
+ # where we will need more complex regexes to execute it all at the same time
14
+ aggregated_tests = Hash.new do |hash, key|
15
+ hash[key] = Hash.new do |inner_h, inner_k|
16
+ inner_h[inner_k] = { tags: Set.new, examples: [] }
17
+ end
18
+ end
19
+
20
+ # Full files are paths that should be executed as a whole e.g.: an entire test file or directory
21
+ full_files = []
22
+ queue = items.dup
23
+
24
+ until queue.empty?
25
+ item = T.must(queue.shift)
26
+ tags = Set.new(item[:tags])
27
+ next unless tags.include?("framework:minitest") || tags.include?("framework:test_unit")
28
+
29
+ children = item[:children]
30
+ uri = URI(item[:uri])
31
+ path = uri.full_path
32
+ next unless path
33
+
34
+ if tags.include?("test_dir")
35
+ if children.empty?
36
+ full_files.concat(Dir.glob(
37
+ "#{path}/**/{*_test,test_*}.rb",
38
+ File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
39
+ ))
40
+ end
41
+ elsif tags.include?("test_file")
42
+ full_files << path if children.empty?
43
+ elsif tags.include?("test_group")
44
+ # If all of the children of the current test group are other groups, then there's no need to add it to the
45
+ # aggregated examples
46
+ unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
47
+ aggregated_tests[path][item[:label]] = { tags: tags, examples: [] }
48
+ end
49
+ else
50
+ class_name, method_name = item[:id].split("#")
51
+ aggregated_tests[path][class_name][:examples] << method_name
52
+ aggregated_tests[path][class_name][:tags].merge(tags)
53
+ end
54
+
55
+ queue.concat(children) unless children.empty?
56
+ end
57
+
58
+ commands = []
59
+
60
+ aggregated_tests.each do |file_path, groups_and_examples|
61
+ # Separate groups into Minitest and Test Unit. You can have both frameworks in the same file, but you cannot
62
+ # have a group belongs to both at the same time
63
+ minitest_groups, test_unit_groups = groups_and_examples.partition do |_, info|
64
+ info[:tags].include?("framework:minitest")
65
+ end
66
+
67
+ if minitest_groups.any?
68
+ commands << handle_minitest_groups(file_path, minitest_groups)
69
+ end
70
+
71
+ if test_unit_groups.any?
72
+ commands.concat(handle_test_unit_groups(file_path, test_unit_groups))
73
+ end
74
+ end
75
+
76
+ unless full_files.empty?
77
+ commands << "#{BASE_COMMAND} -Itest -e \"ARGV.each { |f| require f }\" #{full_files.join(" ")}"
78
+ end
79
+
80
+ commands
81
+ end
82
+
83
+ private
84
+
85
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> String
86
+ def handle_minitest_groups(file_path, groups_and_examples)
87
+ regexes = groups_and_examples.flat_map do |group, info|
88
+ examples = info[:examples]
89
+ group_regex = Shellwords.escape(group).gsub(
90
+ Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
91
+ ".*",
92
+ )
93
+ if examples.empty?
94
+ "^#{group_regex}(#|::)"
95
+ elsif examples.length == 1
96
+ "^#{group_regex}##{examples[0]}$"
97
+ else
98
+ "^#{group_regex}#(#{examples.join("|")})$"
99
+ end
100
+ end
101
+
102
+ regex = if regexes.length == 1
103
+ regexes[0]
104
+ else
105
+ "(#{regexes.join("|")})"
106
+ end
107
+
108
+ "#{BASE_COMMAND} -Itest #{file_path} --name \"/#{regex}/\""
109
+ end
110
+
111
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
112
+ def handle_test_unit_groups(file_path, groups_and_examples)
113
+ groups_and_examples.map do |group, info|
114
+ examples = info[:examples]
115
+ group_regex = Shellwords.escape(group).gsub(
116
+ Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
117
+ ".*",
118
+ )
119
+ command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}$/\""
120
+
121
+ unless examples.empty?
122
+ command << if examples.length == 1
123
+ " --name \"/#{examples[0]}$/\""
124
+ else
125
+ " --name \"/(#{examples.join("|")})$/\""
126
+ end
127
+ end
128
+
129
+ command
130
+ end
131
+ end
132
+ end
133
+
8
134
  include Requests::Support::Common
9
135
 
136
+ MINITEST_REPORTER_PATH = File.expand_path("../ruby_lsp_reporter_plugin.rb", __dir__) #: String
137
+ TEST_UNIT_REPORTER_PATH = File.expand_path("../test_unit_test_runner.rb", __dir__) #: String
10
138
  ACCESS_MODIFIERS = [:public, :private, :protected].freeze
11
- DYNAMIC_REFERENCE_MARKER = "<dynamic_reference>"
12
-
13
- sig do
14
- params(
15
- response_builder: ResponseBuilders::TestCollection,
16
- global_state: GlobalState,
17
- dispatcher: Prism::Dispatcher,
18
- uri: URI::Generic,
19
- ).void
20
- end
139
+ BASE_COMMAND = begin
140
+ Bundler.with_original_env { Bundler.default_lockfile }
141
+ "bundle exec ruby"
142
+ rescue Bundler::GemfileNotFound
143
+ "ruby"
144
+ end #: String
145
+
146
+ #: (ResponseBuilders::TestCollection response_builder, GlobalState global_state, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
21
147
  def initialize(response_builder, global_state, dispatcher, uri)
22
- @response_builder = response_builder
23
- @uri = uri
24
- @index = T.let(global_state.index, RubyIndexer::Index)
25
- @visibility_stack = T.let([:public], T::Array[Symbol])
26
- @nesting = T.let([], T::Array[String])
148
+ super
149
+
150
+ @framework = :minitest #: Symbol
27
151
 
28
152
  dispatcher.register(
29
153
  self,
154
+ # Common handlers registered in parent class
30
155
  :on_class_node_enter,
31
- :on_class_node_leave,
32
- :on_module_node_enter,
33
- :on_module_node_leave,
34
156
  :on_def_node_enter,
35
157
  :on_call_node_enter,
36
158
  :on_call_node_leave,
37
159
  )
38
160
  end
39
161
 
40
- sig { params(node: Prism::ClassNode).void }
162
+ #: (Prism::ClassNode node) -> void
41
163
  def on_class_node_enter(node)
42
- @visibility_stack << :public
43
- name = constant_name(node.constant_path)
44
- name ||= name_with_dynamic_reference(node.constant_path)
45
-
46
- fully_qualified_name = RubyIndexer::Index.actual_nesting(@nesting, name).join("::")
47
-
48
- attached_ancestors = begin
49
- @index.linearized_ancestors_of(fully_qualified_name)
50
- rescue RubyIndexer::Index::NonExistingNamespaceError
51
- # When there are dynamic parts in the constant path, we will not have indexed the namespace. We can still
52
- # provide test functionality if the class inherits directly from Test::Unit::TestCase or Minitest::Test
53
- [node.superclass&.slice].compact
54
- end
55
-
56
- if attached_ancestors.include?("Test::Unit::TestCase") ||
57
- non_declarative_minitest?(attached_ancestors, fully_qualified_name)
58
-
59
- @response_builder.add(Requests::Support::TestItem.new(
60
- fully_qualified_name,
61
- fully_qualified_name,
62
- @uri,
63
- range_from_node(node),
64
- ))
164
+ with_test_ancestor_tracking(node) do |name, ancestors|
165
+ @framework = :test_unit if ancestors.include?("Test::Unit::TestCase")
166
+
167
+ if @framework == :test_unit || non_declarative_minitest?(ancestors, name)
168
+ @response_builder.add(Requests::Support::TestItem.new(
169
+ name,
170
+ name,
171
+ @uri,
172
+ range_from_node(node),
173
+ framework: @framework,
174
+ ))
175
+ end
65
176
  end
66
-
67
- @nesting << name
68
177
  end
69
178
 
70
- sig { params(node: Prism::ModuleNode).void }
71
- def on_module_node_enter(node)
72
- @visibility_stack << :public
73
-
74
- name = constant_name(node.constant_path)
75
- name ||= name_with_dynamic_reference(node.constant_path)
76
-
77
- @nesting << name
78
- end
79
-
80
- sig { params(node: Prism::ModuleNode).void }
81
- def on_module_node_leave(node)
82
- @visibility_stack.pop
83
- @nesting.pop
84
- end
85
-
86
- sig { params(node: Prism::ClassNode).void }
87
- def on_class_node_leave(node)
88
- @visibility_stack.pop
89
- @nesting.pop
90
- end
91
-
92
- sig { params(node: Prism::DefNode).void }
179
+ #: (Prism::DefNode node) -> void
93
180
  def on_def_node_enter(node)
94
181
  return if @visibility_stack.last != :public
95
182
 
@@ -109,10 +196,11 @@ module RubyLsp
109
196
  name,
110
197
  @uri,
111
198
  range_from_node(node),
199
+ framework: @framework,
112
200
  ))
113
201
  end
114
202
 
115
- sig { params(node: Prism::CallNode).void }
203
+ #: (Prism::CallNode node) -> void
116
204
  def on_call_node_enter(node)
117
205
  name = node.name
118
206
  return unless ACCESS_MODIFIERS.include?(name)
@@ -120,7 +208,7 @@ module RubyLsp
120
208
  @visibility_stack << name
121
209
  end
122
210
 
123
- sig { params(node: Prism::CallNode).void }
211
+ #: (Prism::CallNode node) -> void
124
212
  def on_call_node_leave(node)
125
213
  name = node.name
126
214
  return unless ACCESS_MODIFIERS.include?(name)
@@ -131,7 +219,7 @@ module RubyLsp
131
219
 
132
220
  private
133
221
 
134
- sig { params(attached_ancestors: T::Array[String], fully_qualified_name: String).returns(T::Boolean) }
222
+ #: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
135
223
  def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
136
224
  return false unless attached_ancestors.include?("Minitest::Test")
137
225
 
@@ -143,22 +231,6 @@ module RubyLsp
143
231
  rescue RubyIndexer::Index::NonExistingNamespaceError
144
232
  true
145
233
  end
146
-
147
- sig do
148
- params(
149
- node: T.any(
150
- Prism::ConstantPathNode,
151
- Prism::ConstantReadNode,
152
- Prism::ConstantPathTargetNode,
153
- Prism::CallNode,
154
- Prism::MissingNode,
155
- ),
156
- ).returns(String)
157
- end
158
- def name_with_dynamic_reference(node)
159
- slice = node.slice
160
- slice.gsub(/((?<=::)|^)[a-z]\w*/, DYNAMIC_REFERENCE_MARKER)
161
- end
162
234
  end
163
235
  end
164
236
  end
@@ -5,36 +5,19 @@ module RubyLsp
5
5
  # This class allows listeners to access contextual information about a node in the AST, such as its parent,
6
6
  # its namespace nesting, and the surrounding CallNode (e.g. a method call).
7
7
  class NodeContext
8
- extend T::Sig
9
-
10
- sig { returns(T.nilable(Prism::Node)) }
8
+ #: Prism::Node?
11
9
  attr_reader :node, :parent
12
10
 
13
- sig { returns(T::Array[String]) }
11
+ #: Array[String]
14
12
  attr_reader :nesting
15
13
 
16
- sig { returns(T.nilable(Prism::CallNode)) }
14
+ #: Prism::CallNode?
17
15
  attr_reader :call_node
18
16
 
19
- sig { returns(T.nilable(String)) }
17
+ #: String?
20
18
  attr_reader :surrounding_method
21
19
 
22
- sig do
23
- params(
24
- node: T.nilable(Prism::Node),
25
- parent: T.nilable(Prism::Node),
26
- nesting_nodes: T::Array[T.any(
27
- Prism::ClassNode,
28
- Prism::ModuleNode,
29
- Prism::SingletonClassNode,
30
- Prism::DefNode,
31
- Prism::BlockNode,
32
- Prism::LambdaNode,
33
- Prism::ProgramNode,
34
- )],
35
- call_node: T.nilable(Prism::CallNode),
36
- ).void
37
- end
20
+ #: (Prism::Node? node, Prism::Node? parent, Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nesting_nodes, Prism::CallNode? call_node) -> void
38
21
  def initialize(node, parent, nesting_nodes, call_node)
39
22
  @node = node
40
23
  @parent = parent
@@ -42,16 +25,16 @@ module RubyLsp
42
25
  @call_node = call_node
43
26
 
44
27
  nesting, surrounding_method = handle_nesting_nodes(nesting_nodes)
45
- @nesting = T.let(nesting, T::Array[String])
46
- @surrounding_method = T.let(surrounding_method, T.nilable(String))
28
+ @nesting = nesting #: Array[String]
29
+ @surrounding_method = surrounding_method #: String?
47
30
  end
48
31
 
49
- sig { returns(String) }
32
+ #: -> String
50
33
  def fully_qualified_name
51
- @fully_qualified_name ||= T.let(@nesting.join("::"), T.nilable(String))
34
+ @fully_qualified_name ||= @nesting.join("::") #: String?
52
35
  end
53
36
 
54
- sig { returns(T::Array[Symbol]) }
37
+ #: -> Array[Symbol]
55
38
  def locals_for_scope
56
39
  locals = []
57
40
 
@@ -69,20 +52,10 @@ module RubyLsp
69
52
 
70
53
  private
71
54
 
72
- sig do
73
- params(nodes: T::Array[T.any(
74
- Prism::ClassNode,
75
- Prism::ModuleNode,
76
- Prism::SingletonClassNode,
77
- Prism::DefNode,
78
- Prism::BlockNode,
79
- Prism::LambdaNode,
80
- Prism::ProgramNode,
81
- )]).returns([T::Array[String], T.nilable(String)])
82
- end
55
+ #: (Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nodes) -> [Array[String], String?]
83
56
  def handle_nesting_nodes(nodes)
84
57
  nesting = []
85
- surrounding_method = T.let(nil, T.nilable(String))
58
+ surrounding_method = nil #: String?
86
59
 
87
60
  @nesting_nodes.each do |node|
88
61
  case node
@@ -3,18 +3,18 @@
3
3
 
4
4
  module RubyLsp
5
5
  class RBSDocument < Document
6
- extend T::Sig
7
6
  extend T::Generic
8
7
 
9
8
  ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }
10
9
 
11
- sig { params(source: String, version: Integer, uri: URI::Generic, global_state: GlobalState).void }
10
+ #: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
12
11
  def initialize(source:, version:, uri:, global_state:)
13
- @syntax_error = T.let(false, T::Boolean)
12
+ @syntax_error = false #: bool
14
13
  super
15
14
  end
16
15
 
17
- sig { override.returns(T::Boolean) }
16
+ # @override
17
+ #: -> bool
18
18
  def parse!
19
19
  return false unless @needs_parsing
20
20
 
@@ -29,12 +29,14 @@ module RubyLsp
29
29
  true
30
30
  end
31
31
 
32
- sig { override.returns(T::Boolean) }
32
+ # @override
33
+ #: -> bool
33
34
  def syntax_error?
34
35
  @syntax_error
35
36
  end
36
37
 
37
- sig { override.returns(LanguageId) }
38
+ # @override
39
+ #: -> LanguageId
38
40
  def language_id
39
41
  LanguageId::RBS
40
42
  end
@@ -7,7 +7,6 @@ module RubyLsp
7
7
  # request is used to to resolve the edit field for a given code action, if it is not already provided in the
8
8
  # textDocument/codeAction response. We can use it for scenarios that require more computation such as refactoring.
9
9
  class CodeActionResolve < Request
10
- extend T::Sig
11
10
  include Support::Common
12
11
 
13
12
  NEW_VARIABLE_NAME = "new_variable"
@@ -23,7 +22,7 @@ module RubyLsp
23
22
  end
24
23
  end
25
24
 
26
- sig { params(document: RubyDocument, global_state: GlobalState, code_action: T::Hash[Symbol, T.untyped]).void }
25
+ #: (RubyDocument document, GlobalState global_state, Hash[Symbol, untyped] code_action) -> void
27
26
  def initialize(document, global_state, code_action)
28
27
  super()
29
28
  @document = document
@@ -31,7 +30,8 @@ module RubyLsp
31
30
  @code_action = code_action
32
31
  end
33
32
 
34
- sig { override.returns(T.any(Interface::CodeAction, Error)) }
33
+ # @override
34
+ #: -> (Interface::CodeAction | Error)
35
35
  def perform
36
36
  return Error::EmptySelection if @document.source.empty?
37
37
 
@@ -53,7 +53,7 @@ module RubyLsp
53
53
 
54
54
  private
55
55
 
56
- sig { returns(T.any(Interface::CodeAction, Error)) }
56
+ #: -> (Interface::CodeAction | Error)
57
57
  def switch_block_style
58
58
  source_range = @code_action.dig(:data, :range)
59
59
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -91,7 +91,7 @@ module RubyLsp
91
91
  )
92
92
  end
93
93
 
94
- sig { returns(T.any(Interface::CodeAction, Error)) }
94
+ #: -> (Interface::CodeAction | Error)
95
95
  def refactor_variable
96
96
  source_range = @code_action.dig(:data, :range)
97
97
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -189,7 +189,7 @@ module RubyLsp
189
189
  )
190
190
  end
191
191
 
192
- sig { returns(T.any(Interface::CodeAction, Error)) }
192
+ #: -> (Interface::CodeAction | Error)
193
193
  def refactor_method
194
194
  source_range = @code_action.dig(:data, :range)
195
195
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -261,7 +261,7 @@ module RubyLsp
261
261
  )
262
262
  end
263
263
 
264
- sig { params(range: T::Hash[Symbol, T.untyped], new_text: String).returns(Interface::TextEdit) }
264
+ #: (Hash[Symbol, untyped] range, String new_text) -> Interface::TextEdit
265
265
  def create_text_edit(range, new_text)
266
266
  Interface::TextEdit.new(
267
267
  range: Interface::Range.new(
@@ -272,7 +272,7 @@ module RubyLsp
272
272
  )
273
273
  end
274
274
 
275
- sig { params(node: Prism::BlockNode, indentation: T.nilable(String)).returns(String) }
275
+ #: (Prism::BlockNode node, String? indentation) -> String
276
276
  def recursively_switch_nested_block_styles(node, indentation)
277
277
  parameters = node.parameters
278
278
  body = node.body
@@ -301,7 +301,7 @@ module RubyLsp
301
301
  source
302
302
  end
303
303
 
304
- sig { params(body: Prism::Node, indentation: T.nilable(String)).returns(String) }
304
+ #: (Prism::Node body, String? indentation) -> String
305
305
  def switch_block_body(body, indentation)
306
306
  # Check if there are any nested blocks inside of the current block
307
307
  body_loc = body.location
@@ -330,7 +330,7 @@ module RubyLsp
330
330
  indentation ? body_content.gsub(";", "\n") : "#{body_content.gsub("\n", ";")} "
331
331
  end
332
332
 
333
- sig { returns(T.any(Interface::CodeAction, Error)) }
333
+ #: -> (Interface::CodeAction | Error)
334
334
  def create_attribute_accessor
335
335
  source_range = @code_action.dig(:data, :range)
336
336
 
@@ -7,8 +7,6 @@ module RubyLsp
7
7
  # request informs the editor of RuboCop quick fixes that can be applied. These are accessible by hovering over a
8
8
  # specific diagnostic.
9
9
  class CodeActions < Request
10
- extend T::Sig
11
-
12
10
  EXTRACT_TO_VARIABLE_TITLE = "Refactor: Extract Variable"
13
11
  EXTRACT_TO_METHOD_TITLE = "Refactor: Extract Method"
14
12
  TOGGLE_BLOCK_STYLE_TITLE = "Refactor: Toggle block style"
@@ -16,22 +14,17 @@ module RubyLsp
16
14
  CREATE_ATTRIBUTE_WRITER = "Create Attribute Writer"
17
15
  CREATE_ATTRIBUTE_ACCESSOR = "Create Attribute Accessor"
18
16
 
19
- INSTANCE_VARIABLE_NODES = T.let(
20
- [
21
- Prism::InstanceVariableAndWriteNode,
22
- Prism::InstanceVariableOperatorWriteNode,
23
- Prism::InstanceVariableOrWriteNode,
24
- Prism::InstanceVariableReadNode,
25
- Prism::InstanceVariableTargetNode,
26
- Prism::InstanceVariableWriteNode,
27
- ],
28
- T::Array[T.class_of(Prism::Node)],
29
- )
17
+ INSTANCE_VARIABLE_NODES = [
18
+ Prism::InstanceVariableAndWriteNode,
19
+ Prism::InstanceVariableOperatorWriteNode,
20
+ Prism::InstanceVariableOrWriteNode,
21
+ Prism::InstanceVariableReadNode,
22
+ Prism::InstanceVariableTargetNode,
23
+ Prism::InstanceVariableWriteNode,
24
+ ] #: Array[singleton(Prism::Node)]
30
25
 
31
26
  class << self
32
- extend T::Sig
33
-
34
- sig { returns(Interface::CodeActionRegistrationOptions) }
27
+ #: -> Interface::CodeActionRegistrationOptions
35
28
  def provider
36
29
  Interface::CodeActionRegistrationOptions.new(
37
30
  document_selector: nil,
@@ -40,22 +33,17 @@ module RubyLsp
40
33
  end
41
34
  end
42
35
 
43
- sig do
44
- params(
45
- document: T.any(RubyDocument, ERBDocument),
46
- range: T::Hash[Symbol, T.untyped],
47
- context: T::Hash[Symbol, T.untyped],
48
- ).void
49
- end
36
+ #: ((RubyDocument | ERBDocument) document, Hash[Symbol, untyped] range, Hash[Symbol, untyped] context) -> void
50
37
  def initialize(document, range, context)
51
38
  super()
52
39
  @document = document
53
- @uri = T.let(document.uri, URI::Generic)
40
+ @uri = document.uri #: URI::Generic
54
41
  @range = range
55
42
  @context = context
56
43
  end
57
44
 
58
- sig { override.returns(T.nilable(T.all(T::Array[Interface::CodeAction], Object))) }
45
+ # @override
46
+ #: -> (Array[Interface::CodeAction] & Object)?
59
47
  def perform
60
48
  diagnostics = @context[:diagnostics]
61
49
 
@@ -88,7 +76,7 @@ module RubyLsp
88
76
 
89
77
  private
90
78
 
91
- sig { returns(T::Array[Interface::CodeAction]) }
79
+ #: -> Array[Interface::CodeAction]
92
80
  def attribute_actions
93
81
  return [] unless @document.is_a?(RubyDocument)
94
82
 
@@ -11,29 +11,17 @@ module RubyLsp
11
11
  # [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
12
12
  # request informs the editor of runnable commands such as testing and debugging.
13
13
  class CodeLens < Request
14
- extend T::Sig
15
-
16
14
  class << self
17
- extend T::Sig
18
-
19
- sig { returns(Interface::CodeLensOptions) }
15
+ #: -> Interface::CodeLensOptions
20
16
  def provider
21
17
  Interface::CodeLensOptions.new(resolve_provider: false)
22
18
  end
23
19
  end
24
20
 
25
- sig do
26
- params(
27
- global_state: GlobalState,
28
- uri: URI::Generic,
29
- dispatcher: Prism::Dispatcher,
30
- ).void
31
- end
21
+ #: (GlobalState global_state, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
32
22
  def initialize(global_state, uri, dispatcher)
33
- @response_builder = T.let(
34
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens].new,
35
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
36
- )
23
+ @response_builder = ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
24
+ .new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
37
25
  super()
38
26
  Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
39
27
 
@@ -42,7 +30,8 @@ module RubyLsp
42
30
  end
43
31
  end
44
32
 
45
- sig { override.returns(T::Array[Interface::CodeLens]) }
33
+ # @override
34
+ #: -> Array[Interface::CodeLens]
46
35
  def perform
47
36
  @response_builder.response
48
37
  end