ruby-lsp 0.11.1 → 0.11.2

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: b2708af5c4c174d0fafe710fb1f7aaeed7e1aee45cb7aad49f16a53d9f32ad03
4
- data.tar.gz: eaab5153e4c99eac231bf7376ef368fec589e1d6fe05807c9a4de45394242e42
3
+ metadata.gz: 836f512695d45c2b360a2a6533185bd489a7d1c45eda21c0e67a2602cff23712
4
+ data.tar.gz: bdf8fdeefffbb7620ba60cdd91e7e73d7ee9121c5bd810f3456fd46835f5bf5e
5
5
  SHA512:
6
- metadata.gz: ca5c0ba2801350c6557c31b90626a07a4e358245d2177b65a9670f00d2521d0d9850fc488dd65124a58cbc841a09c656d91595cf436391f80e87a434021e822b
7
- data.tar.gz: c8cf7c3228b62639d5b8eb3e3b61750237e85bc43837424359bb54b5d794bea37f0b7214ea6229bfb365c189445d48069dae166e8ad91a0b774bbe34fd269473
6
+ metadata.gz: 4be56dc36e58719d4ccdaea4b720507f21178b0fcfbbc9f634374dd808c33f46872c1cb25dc427f25f007d9b9b1333404c5724e8bbf8bab71ff1a3700c9a766d
7
+ data.tar.gz: 6afc266ad6ae954492d9603e456ba1f65ed00ec6fdc31984b1c42c6597867224d2a230ad165ee2c18afc39d7e5e6eb0f88fc2f4f53e09a724ef67cd4e87e53b2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.1
1
+ 0.11.2
@@ -130,7 +130,7 @@ module RubyIndexer
130
130
  if name.start_with?("::")
131
131
  name = name.delete_prefix("::")
132
132
  results = @entries[name] || @entries[follow_aliased_namespace(name)]
133
- return results.map { |e| e.is_a?(Entry::UnresolvedAlias) ? resolve_alias(e) : e } if results
133
+ return results&.map { |e| e.is_a?(Entry::UnresolvedAlias) ? resolve_alias(e) : e }
134
134
  end
135
135
 
136
136
  nesting.length.downto(0).each do |i|
@@ -161,8 +161,9 @@ module RubyIndexer
161
161
  sig { params(indexable_path: IndexablePath, source: T.nilable(String)).void }
162
162
  def index_single(indexable_path, source = nil)
163
163
  content = source || File.read(indexable_path.full_path)
164
- visitor = IndexVisitor.new(self, YARP.parse(content), indexable_path.full_path)
165
- visitor.run
164
+ result = YARP.parse(content)
165
+ visitor = IndexVisitor.new(self, result, indexable_path.full_path)
166
+ result.value.accept(visitor)
166
167
 
167
168
  require_path = indexable_path.require_path
168
169
  @require_paths_tree.insert(require_path, indexable_path) if require_path
@@ -182,6 +183,8 @@ module RubyIndexer
182
183
  # aliases, so we have to invoke `follow_aliased_namespace` again to check until we only return a real name
183
184
  sig { params(name: String).returns(String) }
184
185
  def follow_aliased_namespace(name)
186
+ return name if @entries[name]
187
+
185
188
  parts = name.split("::")
186
189
  real_parts = []
187
190
 
@@ -8,7 +8,6 @@ module RubyIndexer
8
8
  sig { params(index: Index, parse_result: YARP::ParseResult, file_path: String).void }
9
9
  def initialize(index, parse_result, file_path)
10
10
  @index = index
11
- @parse_result = parse_result
12
11
  @file_path = file_path
13
12
  @stack = T.let([], T::Array[String])
14
13
  @comments_by_line = T.let(
@@ -21,41 +20,84 @@ module RubyIndexer
21
20
  super()
22
21
  end
23
22
 
24
- sig { void }
25
- def run
26
- visit(@parse_result.value)
23
+ sig { override.params(node: YARP::ClassNode).void }
24
+ def visit_class_node(node)
25
+ add_index_entry(node, Index::Entry::Class)
27
26
  end
28
27
 
29
- sig { params(node: T.nilable(YARP::Node)).void }
30
- def visit(node)
31
- case node
32
- when YARP::ProgramNode, YARP::StatementsNode
33
- visit_child_nodes(node)
34
- when YARP::ClassNode
35
- add_index_entry(node, Index::Entry::Class)
36
- when YARP::ModuleNode
37
- add_index_entry(node, Index::Entry::Module)
38
- when YARP::ConstantWriteNode, YARP::ConstantOrWriteNode
39
- name = fully_qualify_name(node.name.to_s)
40
- add_constant(node, name)
41
- when YARP::ConstantPathWriteNode, YARP::ConstantPathOrWriteNode, YARP::ConstantPathOperatorWriteNode,
42
- YARP::ConstantPathAndWriteNode
28
+ sig { override.params(node: YARP::ModuleNode).void }
29
+ def visit_module_node(node)
30
+ add_index_entry(node, Index::Entry::Module)
31
+ end
43
32
 
44
- # ignore variable constants like `var::FOO` or `self.class::FOO`
45
- return unless node.target.parent.nil? || node.target.parent.is_a?(YARP::ConstantReadNode)
33
+ sig { override.params(node: YARP::ConstantPathWriteNode).void }
34
+ def visit_constant_path_write_node(node)
35
+ # ignore variable constants like `var::FOO` or `self.class::FOO`
36
+ target = node.target
37
+ return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
46
38
 
47
- name = fully_qualify_name(node.target.location.slice)
48
- add_constant(node, name)
49
- when YARP::CallNode
50
- message = node.message
51
- handle_private_constant(node) if message == "private_constant"
52
- end
39
+ name = fully_qualify_name(target.location.slice)
40
+ add_constant(node, name)
41
+ end
42
+
43
+ sig { override.params(node: YARP::ConstantPathOrWriteNode).void }
44
+ def visit_constant_path_or_write_node(node)
45
+ # ignore variable constants like `var::FOO` or `self.class::FOO`
46
+ target = node.target
47
+ return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
48
+
49
+ name = fully_qualify_name(target.location.slice)
50
+ add_constant(node, name)
51
+ end
52
+
53
+ sig { override.params(node: YARP::ConstantPathOperatorWriteNode).void }
54
+ def visit_constant_path_operator_write_node(node)
55
+ # ignore variable constants like `var::FOO` or `self.class::FOO`
56
+ target = node.target
57
+ return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
58
+
59
+ name = fully_qualify_name(target.location.slice)
60
+ add_constant(node, name)
61
+ end
62
+
63
+ sig { override.params(node: YARP::ConstantPathAndWriteNode).void }
64
+ def visit_constant_path_and_write_node(node)
65
+ # ignore variable constants like `var::FOO` or `self.class::FOO`
66
+ target = node.target
67
+ return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
68
+
69
+ name = fully_qualify_name(target.location.slice)
70
+ add_constant(node, name)
71
+ end
72
+
73
+ sig { override.params(node: YARP::ConstantWriteNode).void }
74
+ def visit_constant_write_node(node)
75
+ name = fully_qualify_name(node.name.to_s)
76
+ add_constant(node, name)
77
+ end
78
+
79
+ sig { override.params(node: YARP::ConstantOrWriteNode).void }
80
+ def visit_constant_or_write_node(node)
81
+ name = fully_qualify_name(node.name.to_s)
82
+ add_constant(node, name)
83
+ end
84
+
85
+ sig { override.params(node: YARP::ConstantAndWriteNode).void }
86
+ def visit_constant_and_write_node(node)
87
+ name = fully_qualify_name(node.name.to_s)
88
+ add_constant(node, name)
89
+ end
90
+
91
+ sig { override.params(node: YARP::ConstantOperatorWriteNode).void }
92
+ def visit_constant_operator_write_node(node)
93
+ name = fully_qualify_name(node.name.to_s)
94
+ add_constant(node, name)
53
95
  end
54
96
 
55
- # Override to avoid using `map` instead of `each`
56
- sig { params(nodes: T::Array[T.nilable(YARP::Node)]).void }
57
- def visit_all(nodes)
58
- nodes.each { |node| visit(node) }
97
+ sig { override.params(node: YARP::CallNode).void }
98
+ def visit_call_node(node)
99
+ message = node.message
100
+ handle_private_constant(node) if message == "private_constant"
59
101
  end
60
102
 
61
103
  private
@@ -90,6 +132,8 @@ module RubyIndexer
90
132
  node: T.any(
91
133
  YARP::ConstantWriteNode,
92
134
  YARP::ConstantOrWriteNode,
135
+ YARP::ConstantAndWriteNode,
136
+ YARP::ConstantOperatorWriteNode,
93
137
  YARP::ConstantPathWriteNode,
94
138
  YARP::ConstantPathOrWriteNode,
95
139
  YARP::ConstantPathOperatorWriteNode,
@@ -133,7 +177,7 @@ module RubyIndexer
133
177
  comments = collect_comments(node)
134
178
  @index << klass.new(fully_qualify_name(name), @file_path, node.location, comments)
135
179
  @stack << name
136
- visit_child_nodes(node)
180
+ visit(node.body)
137
181
  @stack.pop
138
182
  end
139
183
 
@@ -306,5 +306,23 @@ module RubyIndexer
306
306
  constant = @index["A::M"].first
307
307
  assert_instance_of(Index::Entry::Constant, constant)
308
308
  end
309
+
310
+ def test_indexing_or_and_operator_nodes
311
+ index(<<~RUBY)
312
+ A ||= 1
313
+ B &&= 2
314
+ C &= 3
315
+ D::E ||= 4
316
+ F::G &&= 5
317
+ H::I &= 6
318
+ RUBY
319
+
320
+ assert_entry("A", Index::Entry::Constant, "/fake/path/foo.rb:0-0:0-7")
321
+ assert_entry("B", Index::Entry::Constant, "/fake/path/foo.rb:1-0:1-7")
322
+ assert_entry("C", Index::Entry::Constant, "/fake/path/foo.rb:2-0:2-6")
323
+ assert_entry("D::E", Index::Entry::Constant, "/fake/path/foo.rb:3-0:3-10")
324
+ assert_entry("F::G", Index::Entry::Constant, "/fake/path/foo.rb:4-0:4-10")
325
+ assert_entry("H::I", Index::Entry::Constant, "/fake/path/foo.rb:5-0:5-9")
326
+ end
309
327
  end
310
328
  end
@@ -178,5 +178,20 @@ module RubyIndexer
178
178
 
179
179
  assert_equal("Bar", entries.first.name)
180
180
  end
181
+
182
+ def test_resolving_aliases_to_non_existing_constants_with_conflicting_names
183
+ @index.index_single(IndexablePath.new("/fake", "/fake/path/foo.rb"), <<~RUBY)
184
+ module Foo
185
+ class Float < self
186
+ INFINITY = ::Float::INFINITY
187
+ end
188
+ end
189
+ RUBY
190
+
191
+ entry = @index.resolve("INFINITY", ["Foo", "Float"]).first
192
+ refute_nil(entry)
193
+
194
+ assert_instance_of(Index::Entry::UnresolvedAlias, entry)
195
+ end
181
196
  end
182
197
  end
@@ -7,6 +7,7 @@ require "language_server-protocol"
7
7
  require "bundler"
8
8
  require "uri"
9
9
  require "cgi"
10
+ require "set"
10
11
 
11
12
  require "ruby-lsp"
12
13
  require "ruby_indexer/ruby_indexer"
@@ -166,11 +166,6 @@ module RubyLsp
166
166
  add_simple_range(node)
167
167
  end
168
168
 
169
- sig { params(node: YARP::Node).void }
170
- def on_node(node)
171
- emit_requires_range unless node.is_a?(YARP::CallNode)
172
- end
173
-
174
169
  sig { params(node: YARP::StringConcatNode).void }
175
170
  def on_string_concat(node)
176
171
  left = T.let(node.left, YARP::Node)
@@ -271,6 +266,7 @@ module RubyLsp
271
266
 
272
267
  sig { params(start_line: Integer, end_line: Integer).void }
273
268
  def add_lines_range(start_line, end_line)
269
+ emit_requires_range
274
270
  return if start_line >= end_line
275
271
 
276
272
  @_response << Interface::FoldingRange.new(
@@ -56,7 +56,7 @@ module RubyLsp
56
56
 
57
57
  sig { params(gem_pattern: Regexp).returns(T::Boolean) }
58
58
  def direct_dependency?(gem_pattern)
59
- dependency_keys.grep(gem_pattern).any?
59
+ dependencies.any?(gem_pattern)
60
60
  end
61
61
 
62
62
  sig { returns(T::Boolean) }
@@ -65,16 +65,24 @@ module RubyLsp
65
65
  end
66
66
 
67
67
  sig { returns(T::Array[String]) }
68
- def dependency_keys
69
- @dependency_keys ||= T.let(
68
+ def dependencies
69
+ # NOTE: If changing this behaviour, it's likely that the VS Code extension will also need changed.
70
+ @dependencies ||= T.let(
70
71
  begin
71
72
  Bundler.with_original_env { Bundler.default_gemfile }
72
- Bundler.locked_gems.dependencies.keys
73
+ Bundler.locked_gems.dependencies.keys + gemspec_dependencies
73
74
  rescue Bundler::GemfileNotFound
74
75
  []
75
76
  end,
76
77
  T.nilable(T::Array[String]),
77
78
  )
78
79
  end
80
+
81
+ sig { returns(T::Array[String]) }
82
+ def gemspec_dependencies
83
+ Bundler.locked_gems.sources
84
+ .grep(Bundler::Source::Gemspec)
85
+ .flat_map { _1.gemspec&.dependencies&.map(&:name) }
86
+ end
79
87
  end
80
88
  end
@@ -47,13 +47,10 @@ module RubyLsp
47
47
 
48
48
  sig { returns(Interface::Diagnostic) }
49
49
  def to_lsp_diagnostic
50
- if @offense.correctable?
51
- severity = RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name]
52
- message = @offense.message
53
- else
54
- severity = Constant::DiagnosticSeverity::WARNING
55
- message = "#{@offense.message}\n\nThis offense is not auto-correctable.\n"
56
- end
50
+ severity = RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name]
51
+ message = @offense.message
52
+
53
+ message += "\n\nThis offense is not auto-correctable.\n" unless @offense.correctable?
57
54
 
58
55
  Interface::Diagnostic.new(
59
56
  message: message,
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.11.1
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-04 00:00:00.000000000 Z
11
+ date: 2023-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol