ruby-lsp 0.17.4 → 0.17.6
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 +4 -4
- data/README.md +4 -0
- data/VERSION +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +40 -39
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +120 -25
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +266 -68
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +115 -34
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +33 -3
- data/lib/ruby_indexer/test/index_test.rb +248 -7
- data/lib/ruby_indexer/test/method_test.rb +58 -25
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +259 -0
- data/lib/ruby_indexer/test/test_case.rb +1 -5
- data/lib/ruby_lsp/addon.rb +13 -1
- data/lib/ruby_lsp/document.rb +13 -15
- data/lib/ruby_lsp/erb_document.rb +125 -0
- data/lib/ruby_lsp/global_state.rb +4 -1
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/completion.rb +26 -30
- data/lib/ruby_lsp/listeners/definition.rb +24 -17
- data/lib/ruby_lsp/requests/code_action_resolve.rb +2 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/completion_resolve.rb +2 -7
- data/lib/ruby_lsp/requests/definition.rb +4 -3
- data/lib/ruby_lsp/requests/formatting.rb +2 -0
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +3 -2
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +2 -6
- data/lib/ruby_lsp/ruby_document.rb +10 -0
- data/lib/ruby_lsp/server.rb +41 -11
- data/lib/ruby_lsp/store.rb +23 -8
- data/lib/ruby_lsp/test_helper.rb +2 -0
- metadata +7 -6
@@ -313,12 +313,12 @@ module RubyIndexer
|
|
313
313
|
@index.index_single(indexable_path)
|
314
314
|
end
|
315
315
|
|
316
|
-
refute_empty(@index
|
316
|
+
refute_empty(@index)
|
317
317
|
end
|
318
318
|
|
319
319
|
def test_index_single_does_not_fail_for_non_existing_file
|
320
320
|
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"))
|
321
|
-
entries_after_indexing = @index.
|
321
|
+
entries_after_indexing = @index.names
|
322
322
|
assert_equal(@default_indexed_entries.keys, entries_after_indexing)
|
323
323
|
end
|
324
324
|
|
@@ -1007,6 +1007,43 @@ module RubyIndexer
|
|
1007
1007
|
assert_instance_of(Entry::Alias, baz_entry)
|
1008
1008
|
end
|
1009
1009
|
|
1010
|
+
def test_resolving_constants_in_aliased_namespace
|
1011
|
+
index(<<~RUBY)
|
1012
|
+
module Original
|
1013
|
+
module Something
|
1014
|
+
CONST = 123
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
module Other
|
1019
|
+
ALIAS = Original::Something
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
module Third
|
1023
|
+
Other::ALIAS::CONST
|
1024
|
+
end
|
1025
|
+
RUBY
|
1026
|
+
|
1027
|
+
entry = T.must(@index.resolve("Other::ALIAS::CONST", ["Third"])&.first)
|
1028
|
+
assert_kind_of(Entry::Constant, entry)
|
1029
|
+
assert_equal("Original::Something::CONST", entry.name)
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
def test_resolving_top_level_aliases
|
1033
|
+
index(<<~RUBY)
|
1034
|
+
class Foo
|
1035
|
+
CONST = 123
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
FOO = Foo
|
1039
|
+
FOO::CONST
|
1040
|
+
RUBY
|
1041
|
+
|
1042
|
+
entry = T.must(@index.resolve("FOO::CONST", [])&.first)
|
1043
|
+
assert_kind_of(Entry::Constant, entry)
|
1044
|
+
assert_equal("Foo::CONST", entry.name)
|
1045
|
+
end
|
1046
|
+
|
1010
1047
|
def test_resolving_top_level_compact_reference
|
1011
1048
|
index(<<~RUBY)
|
1012
1049
|
class Foo::Bar
|
@@ -1321,11 +1358,6 @@ module RubyIndexer
|
|
1321
1358
|
entries = @index.instance_variable_completion_candidates("@", "Foo::Bar::<Class:Bar>").map(&:name)
|
1322
1359
|
assert_includes(entries, "@a")
|
1323
1360
|
assert_includes(entries, "@b")
|
1324
|
-
|
1325
|
-
assert_includes(
|
1326
|
-
@index.instance_variable_completion_candidates("@", "Foo::Bar::<Class:Bar>::<Class:<Class:Bar>>").map(&:name),
|
1327
|
-
"@c",
|
1328
|
-
)
|
1329
1361
|
end
|
1330
1362
|
|
1331
1363
|
def test_singletons_are_excluded_from_prefix_search
|
@@ -1472,5 +1504,214 @@ module RubyIndexer
|
|
1472
1504
|
|
1473
1505
|
assert_empty(@index.method_completion_candidates("bar", "Foo"))
|
1474
1506
|
end
|
1507
|
+
|
1508
|
+
def test_completion_does_not_duplicate_overridden_methods
|
1509
|
+
index(<<~RUBY)
|
1510
|
+
class Foo
|
1511
|
+
def bar; end
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
class Baz < Foo
|
1515
|
+
def bar; end
|
1516
|
+
end
|
1517
|
+
RUBY
|
1518
|
+
|
1519
|
+
entries = @index.method_completion_candidates("bar", "Baz")
|
1520
|
+
assert_equal(["bar"], entries.map(&:name))
|
1521
|
+
assert_equal("Baz", T.must(entries.first.owner).name)
|
1522
|
+
end
|
1523
|
+
|
1524
|
+
def test_completion_does_not_duplicate_methods_overridden_by_aliases
|
1525
|
+
index(<<~RUBY)
|
1526
|
+
class Foo
|
1527
|
+
def bar; end
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
class Baz < Foo
|
1531
|
+
alias bar to_s
|
1532
|
+
end
|
1533
|
+
RUBY
|
1534
|
+
|
1535
|
+
entries = @index.method_completion_candidates("bar", "Baz")
|
1536
|
+
assert_equal(["bar"], entries.map(&:name))
|
1537
|
+
assert_equal("Baz", T.must(entries.first.owner).name)
|
1538
|
+
end
|
1539
|
+
|
1540
|
+
def test_decorated_parameters
|
1541
|
+
index(<<~RUBY)
|
1542
|
+
class Foo
|
1543
|
+
def bar(a, b = 1, c: 2)
|
1544
|
+
end
|
1545
|
+
end
|
1546
|
+
RUBY
|
1547
|
+
|
1548
|
+
methods = @index.resolve_method("bar", "Foo")
|
1549
|
+
refute_nil(methods)
|
1550
|
+
|
1551
|
+
entry = T.must(methods.first)
|
1552
|
+
|
1553
|
+
assert_equal("(a, b = <default>, c: <default>)", entry.decorated_parameters)
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
def test_decorated_parameters_when_method_has_no_parameters
|
1557
|
+
index(<<~RUBY)
|
1558
|
+
class Foo
|
1559
|
+
def bar
|
1560
|
+
end
|
1561
|
+
end
|
1562
|
+
RUBY
|
1563
|
+
|
1564
|
+
methods = @index.resolve_method("bar", "Foo")
|
1565
|
+
refute_nil(methods)
|
1566
|
+
|
1567
|
+
entry = T.must(methods.first)
|
1568
|
+
|
1569
|
+
assert_equal("()", entry.decorated_parameters)
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
def test_linearizing_singleton_ancestors_of_singleton_when_class_has_parent
|
1573
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1574
|
+
class Foo; end
|
1575
|
+
|
1576
|
+
class Bar < Foo
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
class Baz < Bar
|
1580
|
+
class << self
|
1581
|
+
class << self
|
1582
|
+
end
|
1583
|
+
end
|
1584
|
+
end
|
1585
|
+
RUBY
|
1586
|
+
|
1587
|
+
assert_equal(
|
1588
|
+
[
|
1589
|
+
"Baz::<Class:Baz>::<Class:<Class:Baz>>",
|
1590
|
+
"Bar::<Class:Bar>::<Class:<Class:Bar>>",
|
1591
|
+
"Foo::<Class:Foo>::<Class:<Class:Foo>>",
|
1592
|
+
"Object::<Class:Object>::<Class:<Class:Object>>",
|
1593
|
+
"BasicObject::<Class:BasicObject>::<Class:<Class:BasicObject>>",
|
1594
|
+
"Class::<Class:Class>",
|
1595
|
+
"Module::<Class:Module>",
|
1596
|
+
"Object::<Class:Object>",
|
1597
|
+
"BasicObject::<Class:BasicObject>",
|
1598
|
+
"Class",
|
1599
|
+
"Module",
|
1600
|
+
"Object",
|
1601
|
+
"Kernel",
|
1602
|
+
"BasicObject",
|
1603
|
+
],
|
1604
|
+
@index.linearized_ancestors_of("Baz::<Class:Baz>::<Class:<Class:Baz>>"),
|
1605
|
+
)
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
def test_linearizing_singleton_object
|
1609
|
+
assert_equal(
|
1610
|
+
[
|
1611
|
+
"Object::<Class:Object>",
|
1612
|
+
"BasicObject::<Class:BasicObject>",
|
1613
|
+
"Class",
|
1614
|
+
"Module",
|
1615
|
+
"Object",
|
1616
|
+
"Kernel",
|
1617
|
+
"BasicObject",
|
1618
|
+
],
|
1619
|
+
@index.linearized_ancestors_of("Object::<Class:Object>"),
|
1620
|
+
)
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
def test_linearizing_singleton_ancestors
|
1624
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1625
|
+
module First
|
1626
|
+
end
|
1627
|
+
|
1628
|
+
module Second
|
1629
|
+
include First
|
1630
|
+
end
|
1631
|
+
|
1632
|
+
module Foo
|
1633
|
+
class Bar
|
1634
|
+
class << self
|
1635
|
+
class Baz
|
1636
|
+
extend Second
|
1637
|
+
|
1638
|
+
class << self
|
1639
|
+
include First
|
1640
|
+
end
|
1641
|
+
end
|
1642
|
+
end
|
1643
|
+
end
|
1644
|
+
end
|
1645
|
+
RUBY
|
1646
|
+
|
1647
|
+
assert_equal(
|
1648
|
+
[
|
1649
|
+
"Foo::Bar::<Class:Bar>::Baz::<Class:Baz>",
|
1650
|
+
"Second",
|
1651
|
+
"First",
|
1652
|
+
"Object::<Class:Object>",
|
1653
|
+
"BasicObject::<Class:BasicObject>",
|
1654
|
+
"Class",
|
1655
|
+
"Module",
|
1656
|
+
"Object",
|
1657
|
+
"Kernel",
|
1658
|
+
"BasicObject",
|
1659
|
+
],
|
1660
|
+
@index.linearized_ancestors_of("Foo::Bar::<Class:Bar>::Baz::<Class:Baz>"),
|
1661
|
+
)
|
1662
|
+
end
|
1663
|
+
|
1664
|
+
def test_linearizing_singleton_ancestors_when_class_has_parent
|
1665
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1666
|
+
class Foo; end
|
1667
|
+
|
1668
|
+
class Bar < Foo
|
1669
|
+
end
|
1670
|
+
|
1671
|
+
class Baz < Bar
|
1672
|
+
class << self
|
1673
|
+
end
|
1674
|
+
end
|
1675
|
+
RUBY
|
1676
|
+
|
1677
|
+
assert_equal(
|
1678
|
+
[
|
1679
|
+
"Baz::<Class:Baz>",
|
1680
|
+
"Bar::<Class:Bar>",
|
1681
|
+
"Foo::<Class:Foo>",
|
1682
|
+
"Object::<Class:Object>",
|
1683
|
+
"BasicObject::<Class:BasicObject>",
|
1684
|
+
"Class",
|
1685
|
+
"Module",
|
1686
|
+
"Object",
|
1687
|
+
"Kernel",
|
1688
|
+
"BasicObject",
|
1689
|
+
],
|
1690
|
+
@index.linearized_ancestors_of("Baz::<Class:Baz>"),
|
1691
|
+
)
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
def test_linearizing_a_module_singleton_class
|
1695
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1696
|
+
module A; end
|
1697
|
+
RUBY
|
1698
|
+
|
1699
|
+
assert_equal(
|
1700
|
+
[
|
1701
|
+
"A::<Class:A>",
|
1702
|
+
"Module",
|
1703
|
+
"Object",
|
1704
|
+
"Kernel",
|
1705
|
+
"BasicObject",
|
1706
|
+
],
|
1707
|
+
@index.linearized_ancestors_of("A::<Class:A>"),
|
1708
|
+
)
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
def test_linearizing_a_singleton_class_with_no_attached
|
1712
|
+
assert_raises(Index::NonExistingNamespaceError) do
|
1713
|
+
@index.linearized_ancestors_of("A::<Class:A>")
|
1714
|
+
end
|
1715
|
+
end
|
1475
1716
|
end
|
1476
1717
|
end
|
@@ -123,8 +123,9 @@ module RubyIndexer
|
|
123
123
|
|
124
124
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
125
125
|
entry = T.must(@index["bar"].first)
|
126
|
-
|
127
|
-
|
126
|
+
parameters = entry.signatures.first.parameters
|
127
|
+
assert_equal(1, parameters.length)
|
128
|
+
parameter = parameters.first
|
128
129
|
assert_equal(:a, parameter.name)
|
129
130
|
assert_instance_of(Entry::RequiredParameter, parameter)
|
130
131
|
end
|
@@ -139,8 +140,9 @@ module RubyIndexer
|
|
139
140
|
|
140
141
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
141
142
|
entry = T.must(@index["bar"].first)
|
142
|
-
|
143
|
-
|
143
|
+
parameters = entry.signatures.first.parameters
|
144
|
+
assert_equal(1, parameters.length)
|
145
|
+
parameter = parameters.first
|
144
146
|
assert_equal(:"(a, (b, ))", parameter.name)
|
145
147
|
assert_instance_of(Entry::RequiredParameter, parameter)
|
146
148
|
end
|
@@ -155,8 +157,9 @@ module RubyIndexer
|
|
155
157
|
|
156
158
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
157
159
|
entry = T.must(@index["bar"].first)
|
158
|
-
|
159
|
-
|
160
|
+
parameters = entry.signatures.first.parameters
|
161
|
+
assert_equal(1, parameters.length)
|
162
|
+
parameter = parameters.first
|
160
163
|
assert_equal(:a, parameter.name)
|
161
164
|
assert_instance_of(Entry::OptionalParameter, parameter)
|
162
165
|
end
|
@@ -171,8 +174,9 @@ module RubyIndexer
|
|
171
174
|
|
172
175
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
173
176
|
entry = T.must(@index["bar"].first)
|
174
|
-
|
175
|
-
|
177
|
+
parameters = entry.signatures.first.parameters
|
178
|
+
assert_equal(2, parameters.length)
|
179
|
+
a, b = parameters
|
176
180
|
|
177
181
|
assert_equal(:a, a.name)
|
178
182
|
assert_instance_of(Entry::KeywordParameter, a)
|
@@ -191,8 +195,9 @@ module RubyIndexer
|
|
191
195
|
|
192
196
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
193
197
|
entry = T.must(@index["bar"].first)
|
194
|
-
|
195
|
-
|
198
|
+
parameters = entry.signatures.first.parameters
|
199
|
+
assert_equal(2, parameters.length)
|
200
|
+
a, b = parameters
|
196
201
|
|
197
202
|
assert_equal(:a, a.name)
|
198
203
|
assert_instance_of(Entry::RestParameter, a)
|
@@ -216,8 +221,9 @@ module RubyIndexer
|
|
216
221
|
|
217
222
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
218
223
|
entry = T.must(@index["bar"].first)
|
219
|
-
|
220
|
-
|
224
|
+
parameters = entry.signatures.first.parameters
|
225
|
+
assert_equal(2, parameters.length)
|
226
|
+
a, b = parameters
|
221
227
|
|
222
228
|
assert_equal(:a, a.name)
|
223
229
|
assert_instance_of(Entry::RestParameter, a)
|
@@ -226,8 +232,9 @@ module RubyIndexer
|
|
226
232
|
assert_instance_of(Entry::RequiredParameter, b)
|
227
233
|
|
228
234
|
entry = T.must(@index["baz"].first)
|
229
|
-
|
230
|
-
|
235
|
+
parameters = entry.signatures.first.parameters
|
236
|
+
assert_equal(2, parameters.length)
|
237
|
+
a, b = parameters
|
231
238
|
|
232
239
|
assert_equal(:a, a.name)
|
233
240
|
assert_instance_of(Entry::KeywordRestParameter, a)
|
@@ -236,8 +243,9 @@ module RubyIndexer
|
|
236
243
|
assert_instance_of(Entry::RequiredParameter, b)
|
237
244
|
|
238
245
|
entry = T.must(@index["qux"].first)
|
239
|
-
|
240
|
-
|
246
|
+
parameters = entry.signatures.first.parameters
|
247
|
+
assert_equal(2, parameters.length)
|
248
|
+
_a, second = parameters
|
241
249
|
|
242
250
|
assert_equal(:"(b, c)", second.name)
|
243
251
|
assert_instance_of(Entry::RequiredParameter, second)
|
@@ -253,8 +261,9 @@ module RubyIndexer
|
|
253
261
|
|
254
262
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
255
263
|
entry = T.must(@index["bar"].first)
|
256
|
-
|
257
|
-
|
264
|
+
parameters = entry.signatures.first.parameters
|
265
|
+
assert_equal(1, parameters.length)
|
266
|
+
param = parameters.first
|
258
267
|
|
259
268
|
assert_equal(:"(a, *b)", param.name)
|
260
269
|
assert_instance_of(Entry::RequiredParameter, param)
|
@@ -272,14 +281,16 @@ module RubyIndexer
|
|
272
281
|
RUBY
|
273
282
|
|
274
283
|
entry = T.must(@index["bar"].first)
|
275
|
-
|
284
|
+
parameters = entry.signatures.first.parameters
|
285
|
+
param = parameters.first
|
276
286
|
assert_equal(:block, param.name)
|
277
287
|
assert_instance_of(Entry::BlockParameter, param)
|
278
288
|
|
279
289
|
entry = T.must(@index["baz"].first)
|
280
|
-
|
290
|
+
parameters = entry.signatures.first.parameters
|
291
|
+
assert_equal(1, parameters.length)
|
281
292
|
|
282
|
-
param =
|
293
|
+
param = parameters.first
|
283
294
|
assert_equal(Entry::BlockParameter::DEFAULT_NAME, param.name)
|
284
295
|
assert_instance_of(Entry::BlockParameter, param)
|
285
296
|
end
|
@@ -294,8 +305,9 @@ module RubyIndexer
|
|
294
305
|
|
295
306
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
296
307
|
entry = T.must(@index["bar"].first)
|
297
|
-
|
298
|
-
|
308
|
+
parameters = entry.signatures.first.parameters
|
309
|
+
assert_equal(2, parameters.length)
|
310
|
+
first, second = parameters
|
299
311
|
|
300
312
|
assert_equal(Entry::RestParameter::DEFAULT_NAME, first.name)
|
301
313
|
assert_instance_of(Entry::RestParameter, first)
|
@@ -314,7 +326,8 @@ module RubyIndexer
|
|
314
326
|
|
315
327
|
assert_entry("bar", Entry::Method, "/fake/path/foo.rb:1-2:2-5")
|
316
328
|
entry = T.must(@index["bar"].first)
|
317
|
-
|
329
|
+
parameters = entry.signatures.first.parameters
|
330
|
+
assert_empty(parameters)
|
318
331
|
end
|
319
332
|
|
320
333
|
def test_keeps_track_of_method_owner
|
@@ -401,7 +414,7 @@ module RubyIndexer
|
|
401
414
|
assert_entry("foo", Entry::UnresolvedMethodAlias, "/fake/path/foo.rb:2-15:2-19")
|
402
415
|
assert_entry("bar", Entry::UnresolvedMethodAlias, "/fake/path/foo.rb:3-15:3-20")
|
403
416
|
# Foo plus 3 valid aliases
|
404
|
-
assert_equal(4, @index.
|
417
|
+
assert_equal(4, @index.length - @default_indexed_entries.length)
|
405
418
|
end
|
406
419
|
|
407
420
|
def test_singleton_methods
|
@@ -428,5 +441,25 @@ module RubyIndexer
|
|
428
441
|
# the exact same
|
429
442
|
assert_same(bar_owner, baz_owner)
|
430
443
|
end
|
444
|
+
|
445
|
+
def test_name_location_points_to_method_identifier_location
|
446
|
+
index(<<~RUBY)
|
447
|
+
class Foo
|
448
|
+
def bar
|
449
|
+
a = 123
|
450
|
+
a + 456
|
451
|
+
end
|
452
|
+
end
|
453
|
+
RUBY
|
454
|
+
|
455
|
+
entry = T.must(@index["bar"].first)
|
456
|
+
refute_equal(entry.location, entry.name_location)
|
457
|
+
|
458
|
+
name_location = entry.name_location
|
459
|
+
assert_equal(2, name_location.start_line)
|
460
|
+
assert_equal(2, name_location.end_line)
|
461
|
+
assert_equal(6, name_location.start_column)
|
462
|
+
assert_equal(9, name_location.end_column)
|
463
|
+
end
|
431
464
|
end
|
432
465
|
end
|