ruby-lsp 0.11.0 → 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7491255b178e72942f0b98ae97c83020c0a5726162d556fba7a2592a2c8b5132
4
- data.tar.gz: d9c61449b9d3eb43a53a8c00b704ceab8691bb404dedd3324d3ad055d859974d
3
+ metadata.gz: 836f512695d45c2b360a2a6533185bd489a7d1c45eda21c0e67a2602cff23712
4
+ data.tar.gz: bdf8fdeefffbb7620ba60cdd91e7e73d7ee9121c5bd810f3456fd46835f5bf5e
5
5
  SHA512:
6
- metadata.gz: 88b6b4d22784336e299caa42e09a701bd9c70ac3176c224c00700ad80605dd8ad17d4274eedc95dad4f6c6432fb192c2094ca8b5ca66ce3ab95bf7ba3eb68831
7
- data.tar.gz: caabe89725f634f87ace44cc85c4d001a8f74dbbb0f2d59f1e2e7a763a3b7896e72a6432abbba7e85e07646ebfc7c812c1126ef8afda520a9f827b58a8cc881d
6
+ metadata.gz: 4be56dc36e58719d4ccdaea4b720507f21178b0fcfbbc9f634374dd808c33f46872c1cb25dc427f25f007d9b9b1333404c5724e8bbf8bab71ff1a3700c9a766d
7
+ data.tar.gz: 6afc266ad6ae954492d9603e456ba1f65ed00ec6fdc31984b1c42c6597867224d2a230ad165ee2c18afc39d7e5e6eb0f88fc2f4f53e09a724ef67cd4e87e53b2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 0.11.2
@@ -179,7 +179,12 @@ module RubyIndexer
179
179
 
180
180
  # When working on a gem, we need to make sure that its gemspec dependencies can't be excluded. This is necessary
181
181
  # because Bundler doesn't assign groups to gemspec dependencies
182
- this_gem = Bundler.definition.dependencies.find { |d| d.to_spec.full_gem_path == Dir.pwd }
182
+ this_gem = Bundler.definition.dependencies.find do |d|
183
+ d.to_spec.full_gem_path == Dir.pwd
184
+ rescue Gem::MissingSpecError
185
+ false
186
+ end
187
+
183
188
  others.concat(this_gem.to_spec.dependencies) if this_gem
184
189
 
185
190
  excluded.each do |dependency|
@@ -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.0
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-03 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