ruby-lsp 0.23.11 → 0.26.1

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +10 -4
  5. data/exe/ruby-lsp-check +0 -4
  6. data/exe/ruby-lsp-launcher +45 -22
  7. data/exe/ruby-lsp-test-exec +6 -0
  8. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
  9. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
  10. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
  15. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  16. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
  17. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
  18. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
  19. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
  20. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
  21. data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
  22. data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
  23. data/lib/ruby_indexer/test/configuration_test.rb +49 -9
  24. data/lib/ruby_indexer/test/constant_test.rb +34 -34
  25. data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
  26. data/lib/ruby_indexer/test/index_test.rb +185 -135
  27. data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
  28. data/lib/ruby_indexer/test/method_test.rb +166 -123
  29. data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
  30. data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
  31. data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
  32. data/lib/ruby_indexer/test/test_case.rb +9 -3
  33. data/lib/ruby_indexer/test/uri_test.rb +15 -2
  34. data/lib/ruby_lsp/addon.rb +88 -86
  35. data/lib/ruby_lsp/base_server.rb +59 -54
  36. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  37. data/lib/ruby_lsp/document.rb +205 -104
  38. data/lib/ruby_lsp/erb_document.rb +45 -47
  39. data/lib/ruby_lsp/global_state.rb +73 -57
  40. data/lib/ruby_lsp/internal.rb +8 -3
  41. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  42. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  43. data/lib/ruby_lsp/listeners/definition.rb +44 -58
  44. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  45. data/lib/ruby_lsp/listeners/document_link.rb +50 -70
  46. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  47. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  48. data/lib/ruby_lsp/listeners/hover.rb +107 -115
  49. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  50. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  51. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  52. data/lib/ruby_lsp/listeners/spec_style.rb +214 -0
  53. data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
  54. data/lib/ruby_lsp/listeners/test_style.rb +205 -95
  55. data/lib/ruby_lsp/node_context.rb +12 -39
  56. data/lib/ruby_lsp/rbs_document.rb +10 -11
  57. data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
  58. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  59. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  60. data/lib/ruby_lsp/requests/completion.rb +8 -21
  61. data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
  62. data/lib/ruby_lsp/requests/definition.rb +8 -20
  63. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  64. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  65. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  66. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  67. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  68. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  69. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  70. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +85 -0
  71. data/lib/ruby_lsp/requests/hover.rb +12 -25
  72. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  73. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  74. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  75. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  76. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  77. data/lib/ruby_lsp/requests/references.rb +17 -57
  78. data/lib/ruby_lsp/requests/rename.rb +27 -51
  79. data/lib/ruby_lsp/requests/request.rb +13 -25
  80. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  81. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  82. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  83. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  84. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  85. data/lib/ruby_lsp/requests/support/common.rb +16 -58
  86. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  87. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  88. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  89. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  90. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  91. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  92. data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
  93. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  94. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  95. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  96. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  97. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  98. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  99. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  100. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  101. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  102. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  103. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  104. data/lib/ruby_lsp/ruby_document.rb +32 -98
  105. data/lib/ruby_lsp/scope.rb +7 -11
  106. data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
  107. data/lib/ruby_lsp/server.rb +303 -196
  108. data/lib/ruby_lsp/setup_bundler.rb +121 -82
  109. data/lib/ruby_lsp/static_docs.rb +12 -7
  110. data/lib/ruby_lsp/store.rb +21 -49
  111. data/lib/ruby_lsp/test_helper.rb +3 -16
  112. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
  113. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  114. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  115. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  116. data/lib/ruby_lsp/utils.rb +138 -93
  117. data/static_docs/break.md +103 -0
  118. metadata +14 -20
  119. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -32,15 +32,13 @@ module RubyLsp
32
32
  module Requests
33
33
  module Support
34
34
  class InternalRuboCopError < StandardError
35
- extend T::Sig
36
-
37
35
  MESSAGE = <<~EOS
38
36
  An internal error occurred %s.
39
37
  Updating to a newer version of RuboCop may solve this.
40
38
  For more details, run RuboCop on the command line.
41
39
  EOS
42
40
 
43
- sig { params(rubocop_error: T.any(::RuboCop::ErrorWithAnalyzedFileLocation, StandardError)).void }
41
+ #: ((::RuboCop::ErrorWithAnalyzedFileLocation | StandardError) rubocop_error) -> void
44
42
  def initialize(rubocop_error)
45
43
  message = case rubocop_error
46
44
  when ::RuboCop::ErrorWithAnalyzedFileLocation
@@ -54,24 +52,19 @@ module RubyLsp
54
52
 
55
53
  # :nodoc:
56
54
  class RuboCopRunner < ::RuboCop::Runner
57
- extend T::Sig
58
-
59
55
  class ConfigurationError < StandardError; end
60
56
 
61
- DEFAULT_ARGS = T.let(
62
- [
63
- "--stderr", # Print any output to stderr so that our stdout does not get polluted
64
- "--force-exclusion",
65
- "--format",
66
- "RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
67
- ],
68
- T::Array[String],
69
- )
70
-
71
- sig { returns(T::Array[::RuboCop::Cop::Offense]) }
57
+ DEFAULT_ARGS = [
58
+ "--stderr", # Print any output to stderr so that our stdout does not get polluted
59
+ "--force-exclusion",
60
+ "--format",
61
+ "RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
62
+ ] #: Array[String]
63
+
64
+ #: Array[::RuboCop::Cop::Offense]
72
65
  attr_reader :offenses
73
66
 
74
- sig { returns(::RuboCop::Config) }
67
+ #: ::RuboCop::Config
75
68
  attr_reader :config_for_working_directory
76
69
 
77
70
  begin
@@ -82,25 +75,26 @@ module RubyLsp
82
75
  end
83
76
  DEFAULT_ARGS.freeze
84
77
 
85
- sig { params(args: String).void }
78
+ #: (*String args) -> void
86
79
  def initialize(*args)
87
- @options = T.let({}, T::Hash[Symbol, T.untyped])
88
- @offenses = T.let([], T::Array[::RuboCop::Cop::Offense])
89
- @errors = T.let([], T::Array[String])
90
- @warnings = T.let([], T::Array[String])
80
+ @options = {} #: Hash[Symbol, untyped]
81
+ @offenses = [] #: Array[::RuboCop::Cop::Offense]
82
+ @errors = [] #: Array[String]
83
+ @warnings = [] #: Array[String]
84
+ # @prism_result = nil #: Prism::ParseLexResult?
91
85
 
92
86
  args += DEFAULT_ARGS
93
87
  rubocop_options = ::RuboCop::Options.new.parse(args).first
94
88
 
95
89
  config_store = ::RuboCop::ConfigStore.new
96
90
  config_store.options_config = rubocop_options[:config] if rubocop_options[:config]
97
- @config_for_working_directory = T.let(config_store.for_pwd, ::RuboCop::Config)
91
+ @config_for_working_directory = config_store.for_pwd #: ::RuboCop::Config
98
92
 
99
93
  super(rubocop_options, config_store)
100
94
  end
101
95
 
102
- sig { params(path: String, contents: String).void }
103
- def run(path, contents)
96
+ #: (String, String, Prism::ParseLexResult) -> void
97
+ def run(path, contents, prism_result)
104
98
  # Clear Runner state between runs since we get a single instance of this class
105
99
  # on every use site.
106
100
  @errors = []
@@ -108,6 +102,11 @@ module RubyLsp
108
102
  @offenses = []
109
103
  @options[:stdin] = contents
110
104
 
105
+ # Setting the Prism result before running the RuboCop runner makes it reuse the existing AST and avoids
106
+ # double-parsing. Unfortunately, this leads to a bunch of cops failing to execute properly under LSP mode.
107
+ # Uncomment this once reusing the Prism result is more stable
108
+ # @prism_result = prism_result
109
+
111
110
  super([path])
112
111
 
113
112
  # RuboCop rescues interrupts and then sets the `@aborting` variable to true. We don't want them to be rescued,
@@ -118,36 +117,35 @@ module RubyLsp
118
117
  rescue ::RuboCop::ValidationError => error
119
118
  raise ConfigurationError, error.message
120
119
  rescue StandardError => error
121
- raise InternalRuboCopError, error
120
+ # Maintain the original backtrace so that debugging cops that are breaking is easier, but re-raise as a
121
+ # different error class
122
+ internal_error = InternalRuboCopError.new(error)
123
+ internal_error.set_backtrace(error.backtrace)
124
+ raise internal_error
122
125
  end
123
126
 
124
- sig { returns(String) }
127
+ #: -> String
125
128
  def formatted_source
126
129
  @options[:stdin]
127
130
  end
128
131
 
129
132
  class << self
130
- extend T::Sig
131
-
132
- sig { params(cop_name: String).returns(T.nilable(T.class_of(::RuboCop::Cop::Base))) }
133
+ #: (String cop_name) -> singleton(::RuboCop::Cop::Base)?
133
134
  def find_cop_by_name(cop_name)
134
135
  cop_registry[cop_name]&.first
135
136
  end
136
137
 
137
138
  private
138
139
 
139
- sig { returns(T::Hash[String, [T.class_of(::RuboCop::Cop::Base)]]) }
140
+ #: -> Hash[String, [singleton(::RuboCop::Cop::Base)]]
140
141
  def cop_registry
141
- @cop_registry ||= T.let(
142
- ::RuboCop::Cop::Registry.global.to_h,
143
- T.nilable(T::Hash[String, [T.class_of(::RuboCop::Cop::Base)]]),
144
- )
142
+ @cop_registry ||= ::RuboCop::Cop::Registry.global.to_h #: Hash[String, [singleton(::RuboCop::Cop::Base)]]?
145
143
  end
146
144
  end
147
145
 
148
146
  private
149
147
 
150
- sig { params(_file: String, offenses: T::Array[::RuboCop::Cop::Offense]).void }
148
+ #: (String _file, Array[::RuboCop::Cop::Offense] offenses) -> void
151
149
  def file_finished(_file, offenses)
152
150
  @offenses = offenses
153
151
  end
@@ -5,9 +5,7 @@ module RubyLsp
5
5
  module Requests
6
6
  module Support
7
7
  class SelectionRange < Interface::SelectionRange
8
- extend T::Sig
9
-
10
- sig { params(position: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
8
+ #: (Hash[Symbol, untyped] position) -> bool
11
9
  def cover?(position)
12
10
  start_covered = range.start.line < position[:line] ||
13
11
  (range.start.line == position[:line] && range.start.character <= position[:character])
@@ -6,45 +6,36 @@ module RubyLsp
6
6
  module Support
7
7
  class Sorbet
8
8
  class << self
9
- extend T::Sig
9
+ ANNOTATIONS = {
10
+ abstract!: Annotation.new(arity: 0),
11
+ absurd: Annotation.new(arity: 1, receiver: true),
12
+ all: Annotation.new(arity: (2..), receiver: true),
13
+ any: Annotation.new(arity: (2..), receiver: true),
14
+ assert_type!: Annotation.new(arity: 2, receiver: true),
15
+ attached_class: Annotation.new(arity: 0, receiver: true),
16
+ bind: Annotation.new(arity: 2, receiver: true),
17
+ cast: Annotation.new(arity: 2, receiver: true),
18
+ class_of: Annotation.new(arity: 1, receiver: true),
19
+ enums: Annotation.new(arity: 0),
20
+ interface!: Annotation.new(arity: 0),
21
+ let: Annotation.new(arity: 2, receiver: true),
22
+ mixes_in_class_methods: Annotation.new(arity: 1),
23
+ must: Annotation.new(arity: 1, receiver: true),
24
+ must_because: Annotation.new(arity: 1, receiver: true),
25
+ nilable: Annotation.new(arity: 1, receiver: true),
26
+ noreturn: Annotation.new(arity: 0, receiver: true),
27
+ requires_ancestor: Annotation.new(arity: 0),
28
+ reveal_type: Annotation.new(arity: 1, receiver: true),
29
+ sealed!: Annotation.new(arity: 0),
30
+ self_type: Annotation.new(arity: 0, receiver: true),
31
+ sig: Annotation.new(arity: 0),
32
+ type_member: Annotation.new(arity: (0..1)),
33
+ type_template: Annotation.new(arity: 0),
34
+ unsafe: Annotation.new(arity: 1),
35
+ untyped: Annotation.new(arity: 0, receiver: true),
36
+ } #: Hash[Symbol, Annotation]
10
37
 
11
- ANNOTATIONS = T.let(
12
- {
13
- abstract!: Annotation.new(arity: 0),
14
- absurd: Annotation.new(arity: 1, receiver: true),
15
- all: Annotation.new(arity: (2..), receiver: true),
16
- any: Annotation.new(arity: (2..), receiver: true),
17
- assert_type!: Annotation.new(arity: 2, receiver: true),
18
- attached_class: Annotation.new(arity: 0, receiver: true),
19
- bind: Annotation.new(arity: 2, receiver: true),
20
- cast: Annotation.new(arity: 2, receiver: true),
21
- class_of: Annotation.new(arity: 1, receiver: true),
22
- enums: Annotation.new(arity: 0),
23
- interface!: Annotation.new(arity: 0),
24
- let: Annotation.new(arity: 2, receiver: true),
25
- mixes_in_class_methods: Annotation.new(arity: 1),
26
- must: Annotation.new(arity: 1, receiver: true),
27
- must_because: Annotation.new(arity: 1, receiver: true),
28
- nilable: Annotation.new(arity: 1, receiver: true),
29
- noreturn: Annotation.new(arity: 0, receiver: true),
30
- requires_ancestor: Annotation.new(arity: 0),
31
- reveal_type: Annotation.new(arity: 1, receiver: true),
32
- sealed!: Annotation.new(arity: 0),
33
- self_type: Annotation.new(arity: 0, receiver: true),
34
- sig: Annotation.new(arity: 0),
35
- type_member: Annotation.new(arity: (0..1)),
36
- type_template: Annotation.new(arity: 0),
37
- unsafe: Annotation.new(arity: 1),
38
- untyped: Annotation.new(arity: 0, receiver: true),
39
- },
40
- T::Hash[Symbol, Annotation],
41
- )
42
-
43
- sig do
44
- params(
45
- node: Prism::CallNode,
46
- ).returns(T::Boolean)
47
- end
38
+ #: (Prism::CallNode node) -> bool
48
39
  def annotation?(node)
49
40
  !!ANNOTATIONS[node.name]&.match?(node)
50
41
  end
@@ -6,43 +6,31 @@ require "uri/file"
6
6
  module URI
7
7
  # Must be kept in sync with the one in Tapioca
8
8
  class Source < URI::File
9
- extend T::Sig
10
-
11
- COMPONENT = T.let(
12
- [
13
- :scheme,
14
- :gem_name,
15
- :gem_version,
16
- :path,
17
- :line_number,
18
- ].freeze,
19
- T::Array[Symbol],
20
- )
9
+ COMPONENT = [
10
+ :scheme,
11
+ :gem_name,
12
+ :gem_version,
13
+ :path,
14
+ :line_number,
15
+ ].freeze #: Array[Symbol]
21
16
 
22
17
  # `uri` for Ruby 3.4 switched the default parser from RFC2396 to RFC3986. The new parser emits a deprecation
23
18
  # warning on a few methods and delegates them to RFC2396, namely `extract`/`make_regexp`/`escape`/`unescape`.
24
19
  # On earlier versions of the uri gem, the RFC2396_PARSER constant doesn't exist, so it needs some special
25
20
  # handling to select a parser that doesn't emit deprecations. While it was backported to Ruby 3.1, users may
26
21
  # have the uri gem in their own bundle and thus not use a compatible version.
27
- PARSER = T.let(const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER, RFC2396_Parser)
22
+ PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser
28
23
 
29
- T.unsafe(self).alias_method(:gem_name, :host)
30
- T.unsafe(self).alias_method(:line_number, :fragment)
24
+ self #: as untyped # rubocop:disable Style/RedundantSelf
25
+ .alias_method(:gem_name, :host)
26
+ self #: as untyped # rubocop:disable Style/RedundantSelf
27
+ .alias_method(:line_number, :fragment)
31
28
 
32
- sig { returns(T.nilable(String)) }
29
+ #: String?
33
30
  attr_reader :gem_version
34
31
 
35
32
  class << self
36
- extend T::Sig
37
-
38
- sig do
39
- params(
40
- gem_name: String,
41
- gem_version: T.nilable(String),
42
- path: String,
43
- line_number: T.nilable(String),
44
- ).returns(URI::Source)
45
- end
33
+ #: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> URI::Source
46
34
  def build(gem_name:, gem_version:, path:, line_number:)
47
35
  super(
48
36
  {
@@ -55,17 +43,17 @@ module URI
55
43
  end
56
44
  end
57
45
 
58
- sig { params(v: T.nilable(String)).void }
46
+ #: (String? v) -> void
59
47
  def set_path(v) # rubocop:disable Naming/AccessorMethodName
60
48
  return if v.nil?
61
49
 
62
50
  gem_version, path = v.delete_prefix("/").split("/", 2)
63
51
 
64
- @gem_version = T.let(gem_version, T.nilable(String))
65
- @path = T.let(path, T.nilable(String))
52
+ @gem_version = gem_version #: String?
53
+ @path = path #: String?
66
54
  end
67
55
 
68
- sig { params(v: T.nilable(String)).returns(T::Boolean) }
56
+ #: (String? v) -> bool
69
57
  def check_host(v)
70
58
  return true unless v
71
59
 
@@ -77,7 +65,7 @@ module URI
77
65
  true
78
66
  end
79
67
 
80
- sig { returns(String) }
68
+ #: -> String
81
69
  def to_s
82
70
  "source://#{gem_name}/#{gem_version}#{path}##{line_number}"
83
71
  end
@@ -85,7 +73,7 @@ module URI
85
73
  if URI.respond_to?(:register_scheme)
86
74
  URI.register_scheme("SOURCE", self)
87
75
  else
88
- @@schemes = T.let(@@schemes, T::Hash[String, T.untyped]) # rubocop:disable Style/ClassVars
76
+ @@schemes = @@schemes #: Hash[String, untyped] # rubocop:disable Style/ClassVars
89
77
  @@schemes["SOURCE"] = self
90
78
  end
91
79
  end
@@ -13,23 +13,19 @@ module RubyLsp
13
13
  module Support
14
14
  # :nodoc:
15
15
  class SyntaxTreeFormatter
16
- extend T::Sig
17
16
  include Support::Formatter
18
17
 
19
- sig { void }
18
+ #: -> void
20
19
  def initialize
21
- @options =
22
- T.let(
23
- begin
24
- opts = SyntaxTree::CLI::Options.new
25
- opts.parse(SyntaxTree::CLI::ConfigFile.new.arguments)
26
- opts
27
- end,
28
- SyntaxTree::CLI::Options,
29
- )
20
+ @options = begin
21
+ opts = SyntaxTree::CLI::Options.new
22
+ opts.parse(SyntaxTree::CLI::ConfigFile.new.arguments)
23
+ opts
24
+ end #: SyntaxTree::CLI::Options
30
25
  end
31
26
 
32
- sig { override.params(uri: URI::Generic, document: RubyDocument).returns(T.nilable(String)) }
27
+ # @override
28
+ #: (URI::Generic uri, RubyDocument document) -> String?
33
29
  def run_formatting(uri, document)
34
30
  path = uri.to_standardized_path
35
31
  return if path && @options.ignore_files.any? { |pattern| File.fnmatch?("*/#{pattern}", path) }
@@ -37,7 +33,8 @@ module RubyLsp
37
33
  SyntaxTree.format(document.source, @options.print_width, options: @options.formatter_options)
38
34
  end
39
35
 
40
- sig { override.params(uri: URI::Generic, source: String, base_indentation: Integer).returns(T.nilable(String)) }
36
+ # @override
37
+ #: (URI::Generic uri, String source, Integer base_indentation) -> String?
41
38
  def run_range_formatting(uri, source, base_indentation)
42
39
  path = uri.to_standardized_path
43
40
  return if path && @options.ignore_files.any? { |pattern| File.fnmatch?("*/#{pattern}", path) }
@@ -45,12 +42,8 @@ module RubyLsp
45
42
  SyntaxTree.format(source, @options.print_width, base_indentation, options: @options.formatter_options)
46
43
  end
47
44
 
48
- sig do
49
- override.params(
50
- uri: URI::Generic,
51
- document: RubyDocument,
52
- ).returns(T.nilable(T::Array[Interface::Diagnostic]))
53
- end
45
+ # @override
46
+ #: (URI::Generic uri, RubyDocument document) -> Array[Interface::Diagnostic]?
54
47
  def run_diagnostic(uri, document)
55
48
  nil
56
49
  end
@@ -10,46 +10,48 @@ module RubyLsp
10
10
  # Note: this test item object can only represent test groups or examples discovered inside files. It cannot be
11
11
  # used to represent test files, directories or workspaces
12
12
  class TestItem
13
- extend T::Sig
14
-
15
- sig { returns(String) }
13
+ #: String
16
14
  attr_reader :id, :label
17
15
 
18
- sig { params(id: String, label: String, uri: URI::Generic, range: Interface::Range).void }
19
- def initialize(id, label, uri, range)
16
+ #: URI::Generic
17
+ attr_reader :uri
18
+
19
+ #: Interface::Range
20
+ attr_reader :range
21
+
22
+ #: (String id, String label, URI::Generic uri, Interface::Range range, framework: Symbol) -> void
23
+ def initialize(id, label, uri, range, framework:)
20
24
  @id = id
21
25
  @label = label
22
26
  @uri = uri
23
27
  @range = range
24
- @children = T.let({}, T::Hash[String, TestItem])
28
+ @tags = ["framework:#{framework}"] #: Array[String]
29
+ @children = {} #: Hash[String, TestItem]
25
30
  end
26
31
 
27
- sig { params(item: TestItem).void }
32
+ #: (TestItem item) -> void
28
33
  def add(item)
29
- if @children.key?(item.id)
30
- raise ResponseBuilders::TestCollection::DuplicateIdError, "TestItem ID is already in use"
31
- end
32
-
33
34
  @children[item.id] = item
34
35
  end
35
36
 
36
- sig { params(id: String).returns(T.nilable(TestItem)) }
37
+ #: (String id) -> TestItem?
37
38
  def [](id)
38
39
  @children[id]
39
40
  end
40
41
 
41
- sig { returns(T::Array[TestItem]) }
42
+ #: -> Array[TestItem]
42
43
  def children
43
44
  @children.values
44
45
  end
45
46
 
46
- sig { returns(T::Hash[Symbol, T.untyped]) }
47
+ #: -> Hash[Symbol, untyped]
47
48
  def to_hash
48
49
  {
49
50
  id: @id,
50
51
  label: @label,
51
52
  uri: @uri,
52
53
  range: @range,
54
+ tags: @tags,
53
55
  children: children.map(&:to_hash),
54
56
  }
55
57
  end
@@ -7,11 +7,9 @@ module RubyLsp
7
7
  # request](https://microsoft.github.io/language-server-protocol/specification#typeHierarchy_supertypes)
8
8
  # displays the list of ancestors (supertypes) for the selected type.
9
9
  class TypeHierarchySupertypes < Request
10
- extend T::Sig
11
-
12
10
  include Support::Common
13
11
 
14
- sig { params(index: RubyIndexer::Index, item: T::Hash[Symbol, T.untyped]).void }
12
+ #: (RubyIndexer::Index index, Hash[Symbol, untyped] item) -> void
15
13
  def initialize(index, item)
16
14
  super()
17
15
 
@@ -19,12 +17,13 @@ module RubyLsp
19
17
  @item = item
20
18
  end
21
19
 
22
- sig { override.returns(T.nilable(T::Array[Interface::TypeHierarchyItem])) }
20
+ # @override
21
+ #: -> Array[Interface::TypeHierarchyItem]?
23
22
  def perform
24
23
  name = @item[:name]
25
24
  entries = @index[name]
26
25
 
27
- parents = T.let(Set.new, T::Set[RubyIndexer::Entry::Namespace])
26
+ parents = Set.new #: Set[RubyIndexer::Entry::Namespace]
28
27
  return unless entries&.any?
29
28
 
30
29
  entries.each do |entry|
@@ -60,7 +59,7 @@ module RubyLsp
60
59
 
61
60
  private
62
61
 
63
- sig { params(entry: RubyIndexer::Entry).returns(Interface::TypeHierarchyItem) }
62
+ #: (RubyIndexer::Entry entry) -> Interface::TypeHierarchyItem
64
63
  def hierarchy_item(entry)
65
64
  Interface::TypeHierarchyItem.new(
66
65
  name: entry.name,
@@ -7,18 +7,18 @@ module RubyLsp
7
7
  # request allows fuzzy searching declarations in the entire project. On VS Code, use CTRL/CMD + T to search for
8
8
  # symbols.
9
9
  class WorkspaceSymbol < Request
10
- extend T::Sig
11
10
  include Support::Common
12
11
 
13
- sig { params(global_state: GlobalState, query: T.nilable(String)).void }
12
+ #: (GlobalState global_state, String? query) -> void
14
13
  def initialize(global_state, query)
15
14
  super()
16
15
  @global_state = global_state
17
16
  @query = query
18
- @index = T.let(global_state.index, RubyIndexer::Index)
17
+ @index = global_state.index #: RubyIndexer::Index
19
18
  end
20
19
 
21
- sig { override.returns(T::Array[Interface::WorkspaceSymbol]) }
20
+ # @override
21
+ #: -> Array[Interface::WorkspaceSymbol]
22
22
  def perform
23
23
  @index.fuzzy_search(@query).filter_map do |entry|
24
24
  uri = entry.uri
@@ -3,24 +3,21 @@
3
3
 
4
4
  module RubyLsp
5
5
  module ResponseBuilders
6
+ #: [ResponseType < Object]
6
7
  class CollectionResponseBuilder < ResponseBuilder
7
- extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { upper: Object } }
11
-
12
- sig { void }
8
+ #: -> void
13
9
  def initialize
14
10
  super
15
- @items = T.let([], T::Array[ResponseType])
11
+ @items = [] #: Array[ResponseType]
16
12
  end
17
13
 
18
- sig { params(item: ResponseType).void }
14
+ #: (ResponseType item) -> void
19
15
  def <<(item)
20
16
  @items << item
21
17
  end
22
18
 
23
- sig { override.returns(T::Array[ResponseType]) }
19
+ # @override
20
+ #: -> Array[ResponseType]
24
21
  def response
25
22
  @items
26
23
  end
@@ -3,54 +3,48 @@
3
3
 
4
4
  module RubyLsp
5
5
  module ResponseBuilders
6
+ #: [ResponseType = Array[Interface::DocumentSymbol]]
6
7
  class DocumentSymbol < ResponseBuilder
7
- extend T::Sig
8
-
9
- ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } }
10
-
11
8
  class SymbolHierarchyRoot
12
- extend T::Sig
13
-
14
- sig { returns(T::Array[Interface::DocumentSymbol]) }
9
+ #: Array[Interface::DocumentSymbol]
15
10
  attr_reader :children
16
11
 
17
- sig { void }
12
+ #: -> void
18
13
  def initialize
19
- @children = T.let([], T::Array[Interface::DocumentSymbol])
14
+ @children = [] #: Array[Interface::DocumentSymbol]
20
15
  end
21
16
  end
22
17
 
23
- sig { void }
18
+ #: -> void
24
19
  def initialize
25
20
  super
26
- @stack = T.let(
27
- [SymbolHierarchyRoot.new],
28
- T::Array[T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)],
29
- )
21
+ @stack = [SymbolHierarchyRoot.new] #: Array[(SymbolHierarchyRoot | Interface::DocumentSymbol)]
30
22
  end
31
23
 
32
- sig { params(symbol: Interface::DocumentSymbol).void }
24
+ #: (Interface::DocumentSymbol symbol) -> void
33
25
  def push(symbol)
34
26
  @stack << symbol
35
27
  end
36
28
 
37
29
  alias_method(:<<, :push)
38
30
 
39
- sig { returns(T.nilable(Interface::DocumentSymbol)) }
31
+ #: -> Interface::DocumentSymbol?
40
32
  def pop
41
33
  if @stack.size > 1
42
- T.cast(@stack.pop, Interface::DocumentSymbol)
34
+ @stack.pop #: as Interface::DocumentSymbol
43
35
  end
44
36
  end
45
37
 
46
- sig { returns(T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)) }
38
+ #: -> (SymbolHierarchyRoot | Interface::DocumentSymbol)
47
39
  def last
48
- T.must(@stack.last)
40
+ @stack.last #: as !nil
49
41
  end
50
42
 
51
- sig { override.returns(T::Array[Interface::DocumentSymbol]) }
43
+ # @override
44
+ #: -> Array[Interface::DocumentSymbol]
52
45
  def response
53
- T.must(@stack.first).children
46
+ @stack.first #: as !nil
47
+ .children
54
48
  end
55
49
  end
56
50
  end
@@ -3,27 +3,20 @@
3
3
 
4
4
  module RubyLsp
5
5
  module ResponseBuilders
6
+ #: [ResponseType = String]
6
7
  class Hover < ResponseBuilder
7
- extend T::Sig
8
- extend T::Generic
9
-
10
- ResponseType = type_member { { fixed: String } }
11
-
12
- sig { void }
8
+ #: -> void
13
9
  def initialize
14
10
  super
15
11
 
16
- @response = T.let(
17
- {
18
- title: +"",
19
- links: +"",
20
- documentation: +"",
21
- },
22
- T::Hash[Symbol, String],
23
- )
12
+ @response = {
13
+ title: +"",
14
+ links: +"",
15
+ documentation: +"",
16
+ } #: Hash[Symbol, String]
24
17
  end
25
18
 
26
- sig { params(content: String, category: Symbol).void }
19
+ #: (String content, category: Symbol) -> void
27
20
  def push(content, category:)
28
21
  hover_content = @response[category]
29
22
  if hover_content
@@ -31,14 +24,15 @@ module RubyLsp
31
24
  end
32
25
  end
33
26
 
34
- sig { returns(T::Boolean) }
27
+ #: -> bool
35
28
  def empty?
36
29
  @response.values.all?(&:empty?)
37
30
  end
38
31
 
39
- sig { override.returns(ResponseType) }
32
+ # @override
33
+ #: -> ResponseType
40
34
  def response
41
- result = T.must(@response[:title])
35
+ result = @response[:title] #: as !nil
42
36
  result << "\n" << @response[:links] if @response[:links]
43
37
  result << "\n" << @response[:documentation] if @response[:documentation]
44
38