ruby-lsp 0.16.7 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/VERSION +1 -1
  4. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +139 -18
  5. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +101 -12
  6. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +183 -10
  7. data/lib/ruby_indexer/test/classes_and_modules_test.rb +55 -9
  8. data/lib/ruby_indexer/test/configuration_test.rb +4 -5
  9. data/lib/ruby_indexer/test/constant_test.rb +8 -8
  10. data/lib/ruby_indexer/test/index_test.rb +528 -0
  11. data/lib/ruby_indexer/test/instance_variables_test.rb +131 -0
  12. data/lib/ruby_indexer/test/method_test.rb +37 -0
  13. data/lib/ruby_indexer/test/test_case.rb +3 -1
  14. data/lib/ruby_lsp/addon.rb +8 -8
  15. data/lib/ruby_lsp/document.rb +3 -3
  16. data/lib/ruby_lsp/internal.rb +1 -0
  17. data/lib/ruby_lsp/listeners/completion.rb +74 -17
  18. data/lib/ruby_lsp/listeners/definition.rb +62 -6
  19. data/lib/ruby_lsp/listeners/hover.rb +60 -6
  20. data/lib/ruby_lsp/listeners/signature_help.rb +4 -4
  21. data/lib/ruby_lsp/node_context.rb +28 -0
  22. data/lib/ruby_lsp/requests/code_action_resolve.rb +73 -2
  23. data/lib/ruby_lsp/requests/code_actions.rb +16 -15
  24. data/lib/ruby_lsp/requests/completion.rb +21 -13
  25. data/lib/ruby_lsp/requests/completion_resolve.rb +9 -0
  26. data/lib/ruby_lsp/requests/definition.rb +20 -5
  27. data/lib/ruby_lsp/requests/document_highlight.rb +2 -2
  28. data/lib/ruby_lsp/requests/hover.rb +5 -6
  29. data/lib/ruby_lsp/requests/on_type_formatting.rb +8 -4
  30. data/lib/ruby_lsp/requests/signature_help.rb +3 -3
  31. data/lib/ruby_lsp/requests/support/common.rb +4 -3
  32. data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -1
  33. data/lib/ruby_lsp/server.rb +10 -4
  34. metadata +4 -2
@@ -24,6 +24,7 @@ module RubyLsp
24
24
  class CodeActionResolve < Request
25
25
  extend T::Sig
26
26
  NEW_VARIABLE_NAME = "new_variable"
27
+ NEW_METHOD_NAME = "new_method"
27
28
 
28
29
  class CodeActionError < StandardError; end
29
30
 
@@ -31,6 +32,7 @@ module RubyLsp
31
32
  enums do
32
33
  EmptySelection = new
33
34
  InvalidTargetRange = new
35
+ UnknownCodeAction = new
34
36
  end
35
37
  end
36
38
 
@@ -43,6 +45,18 @@ module RubyLsp
43
45
 
44
46
  sig { override.returns(T.any(Interface::CodeAction, Error)) }
45
47
  def perform
48
+ case @code_action[:title]
49
+ when CodeActions::EXTRACT_TO_VARIABLE_TITLE
50
+ refactor_variable
51
+ when CodeActions::EXTRACT_TO_METHOD_TITLE
52
+ refactor_method
53
+ else
54
+ Error::UnknownCodeAction
55
+ end
56
+ end
57
+
58
+ sig { returns(T.any(Interface::CodeAction, Error)) }
59
+ def refactor_variable
46
60
  return Error::EmptySelection if @document.source.empty?
47
61
 
48
62
  source_range = @code_action.dig(:data, :range)
@@ -54,9 +68,11 @@ module RubyLsp
54
68
  extracted_source = T.must(@document.source[start_index...end_index])
55
69
 
56
70
  # Find the closest statements node, so that we place the refactor in a valid position
57
- closest_statements, parent_statements = @document
71
+ node_context = @document
58
72
  .locate(@document.tree, start_index, node_types: [Prism::StatementsNode, Prism::BlockNode])
59
73
 
74
+ closest_statements = node_context.node
75
+ parent_statements = node_context.parent
60
76
  return Error::InvalidTargetRange if closest_statements.nil? || closest_statements.child_nodes.compact.empty?
61
77
 
62
78
  # Find the node with the end line closest to the requested position, so that we can place the refactor
@@ -117,7 +133,7 @@ module RubyLsp
117
133
  end
118
134
 
119
135
  Interface::CodeAction.new(
120
- title: "Refactor: Extract Variable",
136
+ title: CodeActions::EXTRACT_TO_VARIABLE_TITLE,
121
137
  edit: Interface::WorkspaceEdit.new(
122
138
  document_changes: [
123
139
  Interface::TextDocumentEdit.new(
@@ -135,6 +151,61 @@ module RubyLsp
135
151
  )
136
152
  end
137
153
 
154
+ sig { returns(T.any(Interface::CodeAction, Error)) }
155
+ def refactor_method
156
+ return Error::EmptySelection if @document.source.empty?
157
+
158
+ source_range = @code_action.dig(:data, :range)
159
+ return Error::EmptySelection if source_range[:start] == source_range[:end]
160
+
161
+ scanner = @document.create_scanner
162
+ start_index = scanner.find_char_position(source_range[:start])
163
+ end_index = scanner.find_char_position(source_range[:end])
164
+ extracted_source = T.must(@document.source[start_index...end_index])
165
+
166
+ # Find the closest method declaration node, so that we place the refactor in a valid position
167
+ node_context = @document.locate(@document.tree, start_index, node_types: [Prism::DefNode])
168
+ closest_def = T.cast(node_context.node, Prism::DefNode)
169
+ return Error::InvalidTargetRange if closest_def.nil?
170
+
171
+ end_keyword_loc = closest_def.end_keyword_loc
172
+ return Error::InvalidTargetRange if end_keyword_loc.nil?
173
+
174
+ end_line = end_keyword_loc.end_line - 1
175
+ character = end_keyword_loc.end_column
176
+ indentation = " " * end_keyword_loc.start_column
177
+ target_range = {
178
+ start: { line: end_line, character: character },
179
+ end: { line: end_line, character: character },
180
+ }
181
+
182
+ new_method_source = <<~RUBY.chomp
183
+
184
+
185
+ #{indentation}def #{NEW_METHOD_NAME}
186
+ #{indentation} #{extracted_source}
187
+ #{indentation}end
188
+ RUBY
189
+
190
+ Interface::CodeAction.new(
191
+ title: CodeActions::EXTRACT_TO_METHOD_TITLE,
192
+ edit: Interface::WorkspaceEdit.new(
193
+ document_changes: [
194
+ Interface::TextDocumentEdit.new(
195
+ text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
196
+ uri: @code_action.dig(:data, :uri),
197
+ version: nil,
198
+ ),
199
+ edits: [
200
+ create_text_edit(target_range, new_method_source),
201
+ create_text_edit(source_range, NEW_METHOD_NAME),
202
+ ],
203
+ ),
204
+ ],
205
+ ),
206
+ )
207
+ end
208
+
138
209
  private
139
210
 
140
211
  sig { params(range: T::Hash[Symbol, T.untyped], new_text: String).returns(Interface::TextEdit) }
@@ -19,6 +19,9 @@ module RubyLsp
19
19
  class CodeActions < Request
20
20
  extend T::Sig
21
21
 
22
+ EXTRACT_TO_VARIABLE_TITLE = "Refactor: Extract Variable"
23
+ EXTRACT_TO_METHOD_TITLE = "Refactor: Extract Method"
24
+
22
25
  class << self
23
26
  extend T::Sig
24
27
 
@@ -52,22 +55,20 @@ module RubyLsp
52
55
  end
53
56
 
54
57
  # Only add refactor actions if there's a non empty selection in the editor
55
- code_actions << refactor_code_action(@range, @uri) unless @range.dig(:start) == @range.dig(:end)
56
- code_actions
57
- end
58
-
59
- private
58
+ unless @range.dig(:start) == @range.dig(:end)
59
+ code_actions << Interface::CodeAction.new(
60
+ title: EXTRACT_TO_VARIABLE_TITLE,
61
+ kind: Constant::CodeActionKind::REFACTOR_EXTRACT,
62
+ data: { range: @range, uri: @uri.to_s },
63
+ )
64
+ code_actions << Interface::CodeAction.new(
65
+ title: EXTRACT_TO_METHOD_TITLE,
66
+ kind: Constant::CodeActionKind::REFACTOR_EXTRACT,
67
+ data: { range: @range, uri: @uri.to_s },
68
+ )
69
+ end
60
70
 
61
- sig { params(range: T::Hash[Symbol, T.untyped], uri: URI::Generic).returns(Interface::CodeAction) }
62
- def refactor_code_action(range, uri)
63
- Interface::CodeAction.new(
64
- title: "Refactor: Extract Variable",
65
- kind: Constant::CodeActionKind::REFACTOR_EXTRACT,
66
- data: {
67
- range: range,
68
- uri: uri.to_s,
69
- },
70
- )
71
+ code_actions
71
72
  end
72
73
  end
73
74
  end
@@ -17,6 +17,7 @@ module RubyLsp
17
17
  # - Constants
18
18
  # - Require paths
19
19
  # - Methods invoked on self only
20
+ # - Instance variables
20
21
  #
21
22
  # # Example
22
23
  #
@@ -35,7 +36,7 @@ module RubyLsp
35
36
  def provider
36
37
  Interface::CompletionOptions.new(
37
38
  resolve_provider: true,
38
- trigger_characters: ["/", "\"", "'", ":"],
39
+ trigger_characters: ["/", "\"", "'", ":", "@"],
39
40
  completion_item: {
40
41
  labelDetailsSupport: true,
41
42
  },
@@ -59,10 +60,20 @@ module RubyLsp
59
60
  # Completion always receives the position immediately after the character that was just typed. Here we adjust it
60
61
  # back by 1, so that we find the right node
61
62
  char_position = document.create_scanner.find_char_position(position) - 1
62
- matched, parent, nesting = document.locate(
63
+ node_context = document.locate(
63
64
  document.tree,
64
65
  char_position,
65
- node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode],
66
+ node_types: [
67
+ Prism::CallNode,
68
+ Prism::ConstantReadNode,
69
+ Prism::ConstantPathNode,
70
+ Prism::InstanceVariableReadNode,
71
+ Prism::InstanceVariableAndWriteNode,
72
+ Prism::InstanceVariableOperatorWriteNode,
73
+ Prism::InstanceVariableOrWriteNode,
74
+ Prism::InstanceVariableTargetNode,
75
+ Prism::InstanceVariableWriteNode,
76
+ ],
66
77
  )
67
78
  @response_builder = T.let(
68
79
  ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem].new,
@@ -72,27 +83,24 @@ module RubyLsp
72
83
  Listeners::Completion.new(
73
84
  @response_builder,
74
85
  global_state,
75
- nesting,
86
+ node_context,
76
87
  typechecker_enabled,
77
88
  dispatcher,
78
89
  document.uri,
79
90
  )
80
91
 
81
92
  Addon.addons.each do |addon|
82
- addon.create_completion_listener(@response_builder, nesting, dispatcher, document.uri)
93
+ addon.create_completion_listener(@response_builder, node_context, dispatcher, document.uri)
83
94
  end
84
95
 
96
+ matched = node_context.node
97
+ parent = node_context.parent
85
98
  return unless matched && parent
86
99
 
87
- @target = case matched
88
- when Prism::CallNode
100
+ @target = if parent.is_a?(Prism::ConstantPathNode) && matched.is_a?(Prism::ConstantReadNode)
101
+ parent
102
+ else
89
103
  matched
90
- when Prism::ConstantReadNode, Prism::ConstantPathNode
91
- if parent.is_a?(Prism::ConstantPathNode) && matched.is_a?(Prism::ConstantReadNode)
92
- parent
93
- else
94
- matched
95
- end
96
104
  end
97
105
  end
98
106
 
@@ -47,6 +47,15 @@ module RubyLsp
47
47
  label = @item[:label]
48
48
  entries = @index[label] || []
49
49
 
50
+ owner_name = @item.dig(:data, :owner_name)
51
+
52
+ if owner_name
53
+ entries = entries.select do |entry|
54
+ (entry.is_a?(RubyIndexer::Entry::Member) || entry.is_a?(RubyIndexer::Entry::InstanceVariable)) &&
55
+ entry.owner&.name == owner_name
56
+ end
57
+ end
58
+
50
59
  @item[:labelDetails] = Interface::CompletionItemLabelDetails.new(
51
60
  description: entries.take(MAX_DOCUMENTATION_ENTRIES).map(&:file_name).join(","),
52
61
  )
@@ -17,7 +17,8 @@ module RubyLsp
17
17
  # - Modules
18
18
  # - Constants
19
19
  # - Require paths
20
- # - Methods invoked on self only
20
+ # - Methods invoked on self only and on receivers where the type is unknown
21
+ # - Instance variables
21
22
  #
22
23
  # # Example
23
24
  #
@@ -46,11 +47,25 @@ module RubyLsp
46
47
  )
47
48
  @dispatcher = dispatcher
48
49
 
49
- target, parent, nesting = document.locate_node(
50
+ node_context = document.locate_node(
50
51
  position,
51
- node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::BlockArgumentNode],
52
+ node_types: [
53
+ Prism::CallNode,
54
+ Prism::ConstantReadNode,
55
+ Prism::ConstantPathNode,
56
+ Prism::BlockArgumentNode,
57
+ Prism::InstanceVariableReadNode,
58
+ Prism::InstanceVariableAndWriteNode,
59
+ Prism::InstanceVariableOperatorWriteNode,
60
+ Prism::InstanceVariableOrWriteNode,
61
+ Prism::InstanceVariableTargetNode,
62
+ Prism::InstanceVariableWriteNode,
63
+ ],
52
64
  )
53
65
 
66
+ target = node_context.node
67
+ parent = node_context.parent
68
+
54
69
  if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
55
70
  # If the target is part of a constant path node, we need to find the exact portion of the constant that the
56
71
  # user is requesting to go to definition for
@@ -71,13 +86,13 @@ module RubyLsp
71
86
  @response_builder,
72
87
  global_state,
73
88
  document.uri,
74
- nesting,
89
+ node_context,
75
90
  dispatcher,
76
91
  typechecker_enabled,
77
92
  )
78
93
 
79
94
  Addon.addons.each do |addon|
80
- addon.create_definition_listener(@response_builder, document.uri, nesting, dispatcher)
95
+ addon.create_definition_listener(@response_builder, document.uri, node_context, dispatcher)
81
96
  end
82
97
  end
83
98
 
@@ -36,12 +36,12 @@ module RubyLsp
36
36
  end
37
37
  def initialize(document, position, dispatcher)
38
38
  super()
39
- target, parent = document.locate_node(position)
39
+ node_context = document.locate_node(position)
40
40
  @response_builder = T.let(
41
41
  ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight].new,
42
42
  ResponseBuilders::CollectionResponseBuilder[Interface::DocumentHighlight],
43
43
  )
44
- Listeners::DocumentHighlight.new(@response_builder, target, parent, dispatcher)
44
+ Listeners::DocumentHighlight.new(@response_builder, node_context.node, node_context.parent, dispatcher)
45
45
  end
46
46
 
47
47
  sig { override.returns(T::Array[Interface::DocumentHighlight]) }
@@ -41,10 +41,9 @@ module RubyLsp
41
41
  end
42
42
  def initialize(document, global_state, position, dispatcher, typechecker_enabled)
43
43
  super()
44
- target, parent, nesting = document.locate_node(
45
- position,
46
- node_types: Listeners::Hover::ALLOWED_TARGETS,
47
- )
44
+ node_context = document.locate_node(position, node_types: Listeners::Hover::ALLOWED_TARGETS)
45
+ target = node_context.node
46
+ parent = node_context.parent
48
47
 
49
48
  if (Listeners::Hover::ALLOWED_TARGETS.include?(parent.class) &&
50
49
  !Listeners::Hover::ALLOWED_TARGETS.include?(target.class)) ||
@@ -66,9 +65,9 @@ module RubyLsp
66
65
  @target = T.let(target, T.nilable(Prism::Node))
67
66
  uri = document.uri
68
67
  @response_builder = T.let(ResponseBuilders::Hover.new, ResponseBuilders::Hover)
69
- Listeners::Hover.new(@response_builder, global_state, uri, nesting, dispatcher, typechecker_enabled)
68
+ Listeners::Hover.new(@response_builder, global_state, uri, node_context, dispatcher, typechecker_enabled)
70
69
  Addon.addons.each do |addon|
71
- addon.create_hover_listener(@response_builder, nesting, dispatcher)
70
+ addon.create_hover_listener(@response_builder, node_context, dispatcher)
72
71
  end
73
72
 
74
73
  @dispatcher = dispatcher
@@ -213,12 +213,13 @@ module RubyLsp
213
213
  sig { void }
214
214
  def auto_indent_after_end_keyword
215
215
  current_line = @lines[@position[:line]]
216
- return unless current_line&.strip == "end"
216
+ return unless current_line && current_line.strip == "end"
217
217
 
218
- target, _parent, _nesting = @document.locate_node({
218
+ node_context = @document.locate_node({
219
219
  line: @position[:line],
220
220
  character: @position[:character] - 1,
221
221
  })
222
+ target = node_context.node
222
223
 
223
224
  statements = case target
224
225
  when Prism::IfNode, Prism::UnlessNode, Prism::ForNode, Prism::WhileNode, Prism::UntilNode
@@ -226,11 +227,14 @@ module RubyLsp
226
227
  end
227
228
  return unless statements
228
229
 
230
+ current_indentation = find_indentation(current_line)
229
231
  statements.body.each do |node|
230
232
  loc = node.location
231
- next unless loc.start_column == @indentation
233
+ next unless loc.start_column == current_indentation
232
234
 
233
- add_edit_with_text(" ", { line: loc.start_line - 1, character: 0 })
235
+ (loc.start_line..loc.end_line).each do |line|
236
+ add_edit_with_text(" ", { line: line - 1, character: 0 })
237
+ end
234
238
  end
235
239
 
236
240
  move_cursor_to(@position[:line], @position[:character])
@@ -51,17 +51,17 @@ module RubyLsp
51
51
  end
52
52
  def initialize(document, global_state, position, context, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
53
53
  super()
54
- target, parent, nesting = document.locate_node(
54
+ node_context = document.locate_node(
55
55
  { line: position[:line], character: position[:character] },
56
56
  node_types: [Prism::CallNode],
57
57
  )
58
58
 
59
- target = adjust_for_nested_target(target, parent, position)
59
+ target = adjust_for_nested_target(node_context.node, node_context.parent, position)
60
60
 
61
61
  @target = T.let(target, T.nilable(Prism::Node))
62
62
  @dispatcher = dispatcher
63
63
  @response_builder = T.let(ResponseBuilders::SignatureHelp.new, ResponseBuilders::SignatureHelp)
64
- Listeners::SignatureHelp.new(@response_builder, global_state, nesting, dispatcher, typechecker_enabled)
64
+ Listeners::SignatureHelp.new(@response_builder, global_state, node_context, dispatcher, typechecker_enabled)
65
65
  end
66
66
 
67
67
  sig { override.returns(T.nilable(Interface::SignatureHelp)) }
@@ -50,12 +50,12 @@ module RubyLsp
50
50
  params(
51
51
  node: Prism::Node,
52
52
  title: String,
53
- command_name: T.nilable(String),
53
+ command_name: String,
54
54
  arguments: T.nilable(T::Array[T.untyped]),
55
55
  data: T.nilable(T::Hash[T.untyped, T.untyped]),
56
56
  ).returns(Interface::CodeLens)
57
57
  end
58
- def create_code_lens(node, title:, command_name: nil, arguments: nil, data: nil)
58
+ def create_code_lens(node, title:, command_name:, arguments:, data:)
59
59
  range = range_from_node(node)
60
60
 
61
61
  Interface::CodeLens.new(
@@ -155,7 +155,8 @@ module RubyLsp
155
155
  end
156
156
  def constant_name(node)
157
157
  node.full_name
158
- rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError
158
+ rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
159
+ Prism::ConstantPathNode::MissingNodesInConstantPathError
159
160
  nil
160
161
  end
161
162
 
@@ -39,7 +39,7 @@ module RubyLsp
39
39
  next if @global_state.typechecker && not_in_dependencies?(file_path)
40
40
 
41
41
  # We should never show private symbols when searching the entire workspace
42
- next if entry.visibility == :private
42
+ next if entry.private?
43
43
 
44
44
  kind = kind_for_entry(entry)
45
45
  loc = entry.location
@@ -79,6 +79,8 @@ module RubyLsp
79
79
  entry.name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
80
80
  when RubyIndexer::Entry::Accessor
81
81
  Constant::SymbolKind::PROPERTY
82
+ when RubyIndexer::Entry::InstanceVariable
83
+ Constant::SymbolKind::FIELD
82
84
  end
83
85
  end
84
86
  end
@@ -104,7 +104,7 @@ module RubyLsp
104
104
  ),
105
105
  )
106
106
 
107
- $stderr.puts(errored_addons.map(&:backtraces).join("\n\n"))
107
+ $stderr.puts(errored_addons.map(&:errors_details).join("\n\n"))
108
108
  end
109
109
  end
110
110
 
@@ -134,7 +134,7 @@ module RubyLsp
134
134
  when Hash
135
135
  # If the configuration is already a hash, merge it with a default value of `true`. That way clients don't have
136
136
  # to opt-in to every single feature
137
- Hash.new(true).merge!(configured_features)
137
+ Hash.new(true).merge!(configured_features.transform_keys(&:to_s))
138
138
  else
139
139
  # If no configuration was passed by the client, just enable every feature
140
140
  Hash.new(true)
@@ -498,6 +498,13 @@ module RubyLsp
498
498
  ),
499
499
  )
500
500
  raise Requests::CodeActionResolve::CodeActionError
501
+ when Requests::CodeActionResolve::Error::UnknownCodeAction
502
+ send_message(
503
+ Notification.window_show_error(
504
+ "Unknown code action",
505
+ ),
506
+ )
507
+ raise Requests::CodeActionResolve::CodeActionError
501
508
  else
502
509
  send_message(Result.new(id: message[:id], response: result))
503
510
  end
@@ -619,8 +626,7 @@ module RubyLsp
619
626
  when Constant::FileChangeType::CREATED
620
627
  index.index_single(indexable)
621
628
  when Constant::FileChangeType::CHANGED
622
- index.delete(indexable)
623
- index.index_single(indexable)
629
+ index.handle_change(indexable)
624
630
  when Constant::FileChangeType::DELETED
625
631
  index.delete(indexable)
626
632
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.7
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-22 00:00:00.000000000 Z
11
+ date: 2024-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol
@@ -90,6 +90,7 @@ files:
90
90
  - lib/ruby_indexer/test/configuration_test.rb
91
91
  - lib/ruby_indexer/test/constant_test.rb
92
92
  - lib/ruby_indexer/test/index_test.rb
93
+ - lib/ruby_indexer/test/instance_variables_test.rb
93
94
  - lib/ruby_indexer/test/method_test.rb
94
95
  - lib/ruby_indexer/test/prefix_tree_test.rb
95
96
  - lib/ruby_indexer/test/test_case.rb
@@ -111,6 +112,7 @@ files:
111
112
  - lib/ruby_lsp/listeners/semantic_highlighting.rb
112
113
  - lib/ruby_lsp/listeners/signature_help.rb
113
114
  - lib/ruby_lsp/load_sorbet.rb
115
+ - lib/ruby_lsp/node_context.rb
114
116
  - lib/ruby_lsp/parameter_scope.rb
115
117
  - lib/ruby_lsp/requests.rb
116
118
  - lib/ruby_lsp/requests/code_action_resolve.rb