ruby-lsp 0.17.3 → 0.17.5
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 +251 -100
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +173 -114
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +337 -77
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +43 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +79 -3
- data/lib/ruby_indexer/test/index_test.rb +563 -29
- data/lib/ruby_indexer/test/instance_variables_test.rb +84 -7
- data/lib/ruby_indexer/test/method_test.rb +75 -25
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +38 -2
- data/lib/ruby_indexer/test/test_case.rb +1 -5
- data/lib/ruby_lsp/addon.rb +13 -1
- data/lib/ruby_lsp/document.rb +50 -23
- data/lib/ruby_lsp/erb_document.rb +125 -0
- data/lib/ruby_lsp/global_state.rb +11 -4
- data/lib/ruby_lsp/internal.rb +3 -0
- data/lib/ruby_lsp/listeners/completion.rb +69 -34
- data/lib/ruby_lsp/listeners/definition.rb +34 -23
- data/lib/ruby_lsp/listeners/hover.rb +14 -7
- data/lib/ruby_lsp/listeners/signature_help.rb +5 -2
- data/lib/ruby_lsp/node_context.rb +6 -1
- data/lib/ruby_lsp/requests/code_action_resolve.rb +2 -2
- data/lib/ruby_lsp/requests/completion.rb +6 -5
- data/lib/ruby_lsp/requests/completion_resolve.rb +7 -4
- data/lib/ruby_lsp/requests/definition.rb +4 -3
- data/lib/ruby_lsp/requests/formatting.rb +2 -0
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +88 -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/support/common.rb +19 -1
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -4
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +87 -0
- data/lib/ruby_lsp/requests/workspace_symbol.rb +1 -21
- data/lib/ruby_lsp/requests.rb +2 -0
- data/lib/ruby_lsp/ruby_document.rb +10 -0
- data/lib/ruby_lsp/server.rb +95 -26
- data/lib/ruby_lsp/store.rb +23 -8
- data/lib/ruby_lsp/test_helper.rb +3 -1
- data/lib/ruby_lsp/type_inferrer.rb +86 -0
- metadata +10 -6
@@ -93,30 +93,30 @@ module RubyIndexer
|
|
93
93
|
|
94
94
|
def test_fuzzy_search
|
95
95
|
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
96
|
-
class
|
96
|
+
class Zws; end
|
97
97
|
|
98
|
-
module
|
99
|
-
class
|
98
|
+
module Qtl
|
99
|
+
class Zws
|
100
100
|
end
|
101
101
|
|
102
|
-
class
|
102
|
+
class Zwo
|
103
103
|
class Something
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
107
107
|
RUBY
|
108
108
|
|
109
|
-
result = @index.fuzzy_search("
|
110
|
-
assert_equal(
|
111
|
-
assert_equal(["
|
112
|
-
|
113
|
-
result = @index.fuzzy_search("foobarsomeking")
|
114
|
-
assert_equal(6, result.length)
|
115
|
-
assert_equal(["Foo::Baz::Something", "Foo::Bar", "Foo::Baz", "Foo", "Base", "Bar"], result.map(&:name))
|
109
|
+
result = @index.fuzzy_search("Zws")
|
110
|
+
assert_equal(2, result.length)
|
111
|
+
assert_equal(["Zws", "Qtl::Zwo::Something"], result.map(&:name))
|
116
112
|
|
117
|
-
result = @index.fuzzy_search("
|
113
|
+
result = @index.fuzzy_search("qtlzwssomeking")
|
118
114
|
assert_equal(5, result.length)
|
119
|
-
assert_equal(["
|
115
|
+
assert_equal(["Qtl::Zwo::Something", "Qtl::Zws", "Qtl::Zwo", "Qtl", "Zws"], result.map(&:name))
|
116
|
+
|
117
|
+
result = @index.fuzzy_search("QltZwo")
|
118
|
+
assert_equal(4, result.length)
|
119
|
+
assert_equal(["Qtl::Zwo", "Qtl::Zws", "Qtl::Zwo::Something", "Qtl"], result.map(&:name))
|
120
120
|
end
|
121
121
|
|
122
122
|
def test_index_single_ignores_directories
|
@@ -140,25 +140,23 @@ module RubyIndexer
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def test_searching_for_entries_based_on_prefix
|
143
|
-
# For this test, it's easier if we don't include core classes and modules
|
144
|
-
@index = Index.new
|
145
143
|
@index.index_single(IndexablePath.new("/fake", "/fake/path/foo.rb"), <<~RUBY)
|
146
|
-
class Foo::
|
144
|
+
class Foo::Bizw
|
147
145
|
end
|
148
146
|
RUBY
|
149
147
|
@index.index_single(IndexablePath.new("/fake", "/fake/path/other_foo.rb"), <<~RUBY)
|
150
|
-
class Foo::
|
148
|
+
class Foo::Bizw
|
151
149
|
end
|
152
150
|
|
153
|
-
class Foo::
|
151
|
+
class Foo::Bizt
|
154
152
|
end
|
155
153
|
RUBY
|
156
154
|
|
157
155
|
results = @index.prefix_search("Foo", []).map { |entries| entries.map(&:name) }
|
158
|
-
assert_equal([["Foo::
|
156
|
+
assert_equal([["Foo::Bizw", "Foo::Bizw"], ["Foo::Bizt"]], results)
|
159
157
|
|
160
|
-
results = @index.prefix_search("
|
161
|
-
assert_equal([["Foo::
|
158
|
+
results = @index.prefix_search("Biz", ["Foo"]).map { |entries| entries.map(&:name) }
|
159
|
+
assert_equal([["Foo::Bizw", "Foo::Bizw"], ["Foo::Bizt"]], results)
|
162
160
|
end
|
163
161
|
|
164
162
|
def test_resolve_normalizes_top_level_names
|
@@ -291,16 +289,16 @@ module RubyIndexer
|
|
291
289
|
index(<<~RUBY)
|
292
290
|
module Foo
|
293
291
|
module Bar
|
294
|
-
def
|
292
|
+
def qzx; end
|
295
293
|
end
|
296
294
|
end
|
297
295
|
RUBY
|
298
296
|
|
299
|
-
entries = @index.prefix_search("
|
297
|
+
entries = @index.prefix_search("qz")
|
300
298
|
refute_empty(entries)
|
301
299
|
|
302
|
-
entry = T.must(entries.first).first
|
303
|
-
assert_equal("
|
300
|
+
entry = T.must(T.must(entries.first).first)
|
301
|
+
assert_equal("qzx", entry.name)
|
304
302
|
end
|
305
303
|
|
306
304
|
def test_indexing_prism_fixtures_succeeds
|
@@ -315,12 +313,12 @@ module RubyIndexer
|
|
315
313
|
@index.index_single(indexable_path)
|
316
314
|
end
|
317
315
|
|
318
|
-
refute_empty(@index
|
316
|
+
refute_empty(@index)
|
319
317
|
end
|
320
318
|
|
321
319
|
def test_index_single_does_not_fail_for_non_existing_file
|
322
320
|
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"))
|
323
|
-
entries_after_indexing = @index.
|
321
|
+
entries_after_indexing = @index.names
|
324
322
|
assert_equal(@default_indexed_entries.keys, entries_after_indexing)
|
325
323
|
end
|
326
324
|
|
@@ -1009,6 +1007,43 @@ module RubyIndexer
|
|
1009
1007
|
assert_instance_of(Entry::Alias, baz_entry)
|
1010
1008
|
end
|
1011
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
|
+
|
1012
1047
|
def test_resolving_top_level_compact_reference
|
1013
1048
|
index(<<~RUBY)
|
1014
1049
|
class Foo::Bar
|
@@ -1145,8 +1180,32 @@ module RubyIndexer
|
|
1145
1180
|
assert_nil(@index.resolve("RSpec", []))
|
1146
1181
|
end
|
1147
1182
|
|
1183
|
+
def test_object_superclass_indexing_and_resolution_with_reopened_object_class
|
1184
|
+
index(<<~RUBY)
|
1185
|
+
class Object; end
|
1186
|
+
RUBY
|
1187
|
+
|
1188
|
+
entries = @index["Object"]
|
1189
|
+
assert_equal(2, entries.length)
|
1190
|
+
reopened_entry = entries.last
|
1191
|
+
assert_equal("::BasicObject", reopened_entry.parent_class)
|
1192
|
+
assert_equal(["Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Object"))
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
def test_object_superclass_indexing_and_resolution_with_reopened_basic_object_class
|
1196
|
+
index(<<~RUBY)
|
1197
|
+
class BasicObject; end
|
1198
|
+
RUBY
|
1199
|
+
|
1200
|
+
entries = @index["BasicObject"]
|
1201
|
+
assert_equal(2, entries.length)
|
1202
|
+
reopened_entry = entries.last
|
1203
|
+
assert_nil(reopened_entry.parent_class)
|
1204
|
+
assert_equal(["BasicObject"], @index.linearized_ancestors_of("BasicObject"))
|
1205
|
+
end
|
1206
|
+
|
1148
1207
|
def test_object_superclass_resolution
|
1149
|
-
|
1208
|
+
index(<<~RUBY)
|
1150
1209
|
module Foo
|
1151
1210
|
class Object; end
|
1152
1211
|
|
@@ -1162,8 +1221,25 @@ module RubyIndexer
|
|
1162
1221
|
)
|
1163
1222
|
end
|
1164
1223
|
|
1224
|
+
def test_basic_object_superclass_resolution
|
1225
|
+
index(<<~RUBY)
|
1226
|
+
module Foo
|
1227
|
+
class BasicObject; end
|
1228
|
+
|
1229
|
+
class Bar; end
|
1230
|
+
class Baz < BasicObject; end
|
1231
|
+
end
|
1232
|
+
RUBY
|
1233
|
+
|
1234
|
+
assert_equal(["Foo::Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Foo::Bar"))
|
1235
|
+
assert_equal(
|
1236
|
+
["Foo::Baz", "Foo::BasicObject", "Object", "Kernel", "BasicObject"],
|
1237
|
+
@index.linearized_ancestors_of("Foo::Baz"),
|
1238
|
+
)
|
1239
|
+
end
|
1240
|
+
|
1165
1241
|
def test_top_level_object_superclass_resolution
|
1166
|
-
|
1242
|
+
index(<<~RUBY)
|
1167
1243
|
module Foo
|
1168
1244
|
class Object; end
|
1169
1245
|
|
@@ -1173,5 +1249,463 @@ module RubyIndexer
|
|
1173
1249
|
|
1174
1250
|
assert_equal(["Foo::Bar", "Object", "Kernel", "BasicObject"], @index.linearized_ancestors_of("Foo::Bar"))
|
1175
1251
|
end
|
1252
|
+
|
1253
|
+
def test_top_level_basic_object_superclass_resolution
|
1254
|
+
index(<<~RUBY)
|
1255
|
+
module Foo
|
1256
|
+
class BasicObject; end
|
1257
|
+
|
1258
|
+
class Bar < ::BasicObject; end
|
1259
|
+
end
|
1260
|
+
RUBY
|
1261
|
+
|
1262
|
+
assert_equal(["Foo::Bar", "BasicObject"], @index.linearized_ancestors_of("Foo::Bar"))
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
def test_resolving_method_inside_singleton_context
|
1266
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1267
|
+
module Foo
|
1268
|
+
class Bar
|
1269
|
+
class << self
|
1270
|
+
class Baz
|
1271
|
+
class << self
|
1272
|
+
def found_me!; end
|
1273
|
+
end
|
1274
|
+
end
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
end
|
1278
|
+
RUBY
|
1279
|
+
|
1280
|
+
entry = @index.resolve_method("found_me!", "Foo::Bar::<Class:Bar>::Baz::<Class:Baz>")&.first
|
1281
|
+
refute_nil(entry)
|
1282
|
+
|
1283
|
+
assert_equal("found_me!", T.must(entry).name)
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
def test_resolving_constants_in_singleton_contexts
|
1287
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1288
|
+
module Foo
|
1289
|
+
class Bar
|
1290
|
+
CONST = 3
|
1291
|
+
|
1292
|
+
class << self
|
1293
|
+
CONST = 2
|
1294
|
+
|
1295
|
+
class Baz
|
1296
|
+
CONST = 1
|
1297
|
+
|
1298
|
+
class << self
|
1299
|
+
end
|
1300
|
+
end
|
1301
|
+
end
|
1302
|
+
end
|
1303
|
+
end
|
1304
|
+
RUBY
|
1305
|
+
|
1306
|
+
entry = @index.resolve("CONST", ["Foo", "Bar", "<Class:Bar>", "Baz", "<Class:Baz>"])&.first
|
1307
|
+
refute_nil(entry)
|
1308
|
+
assert_equal(9, T.must(entry).location.start_line)
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
def test_resolving_instance_variables_in_singleton_contexts
|
1312
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1313
|
+
module Foo
|
1314
|
+
class Bar
|
1315
|
+
@a = 123
|
1316
|
+
|
1317
|
+
class << self
|
1318
|
+
def hello
|
1319
|
+
@b = 123
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
@c = 123
|
1323
|
+
end
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
RUBY
|
1327
|
+
|
1328
|
+
entry = @index.resolve_instance_variable("@a", "Foo::Bar::<Class:Bar>")&.first
|
1329
|
+
refute_nil(entry)
|
1330
|
+
assert_equal("@a", T.must(entry).name)
|
1331
|
+
|
1332
|
+
entry = @index.resolve_instance_variable("@b", "Foo::Bar::<Class:Bar>")&.first
|
1333
|
+
refute_nil(entry)
|
1334
|
+
assert_equal("@b", T.must(entry).name)
|
1335
|
+
|
1336
|
+
entry = @index.resolve_instance_variable("@c", "Foo::Bar::<Class:Bar>::<Class:<Class:Bar>>")&.first
|
1337
|
+
refute_nil(entry)
|
1338
|
+
assert_equal("@c", T.must(entry).name)
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
def test_instance_variable_completion_in_singleton_contexts
|
1342
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1343
|
+
module Foo
|
1344
|
+
class Bar
|
1345
|
+
@a = 123
|
1346
|
+
|
1347
|
+
class << self
|
1348
|
+
def hello
|
1349
|
+
@b = 123
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
@c = 123
|
1353
|
+
end
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
RUBY
|
1357
|
+
|
1358
|
+
entries = @index.instance_variable_completion_candidates("@", "Foo::Bar::<Class:Bar>").map(&:name)
|
1359
|
+
assert_includes(entries, "@a")
|
1360
|
+
assert_includes(entries, "@b")
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
def test_singletons_are_excluded_from_prefix_search
|
1364
|
+
index(<<~RUBY)
|
1365
|
+
class Zwq
|
1366
|
+
class << self
|
1367
|
+
end
|
1368
|
+
end
|
1369
|
+
RUBY
|
1370
|
+
|
1371
|
+
assert_empty(@index.prefix_search("Zwq::<C"))
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
def test_singletons_are_excluded_from_fuzzy_search
|
1375
|
+
index(<<~RUBY)
|
1376
|
+
class Zwq
|
1377
|
+
class << self
|
1378
|
+
end
|
1379
|
+
end
|
1380
|
+
RUBY
|
1381
|
+
|
1382
|
+
results = @index.fuzzy_search("Zwq")
|
1383
|
+
assert_equal(1, results.length)
|
1384
|
+
assert_equal("Zwq", results.first.name)
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
def test_resolving_method_aliases
|
1388
|
+
index(<<~RUBY)
|
1389
|
+
class Foo
|
1390
|
+
def bar(a, b, c)
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
alias double_alias bar
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
class Bar < Foo
|
1397
|
+
def hello(b); end
|
1398
|
+
|
1399
|
+
alias baz bar
|
1400
|
+
alias_method :qux, :hello
|
1401
|
+
alias double double_alias
|
1402
|
+
end
|
1403
|
+
RUBY
|
1404
|
+
|
1405
|
+
# baz
|
1406
|
+
methods = @index.resolve_method("baz", "Bar")
|
1407
|
+
refute_nil(methods)
|
1408
|
+
|
1409
|
+
entry = T.must(methods.first)
|
1410
|
+
assert_kind_of(Entry::MethodAlias, entry)
|
1411
|
+
assert_equal("bar", entry.target.name)
|
1412
|
+
assert_equal("Foo", T.must(entry.target.owner).name)
|
1413
|
+
|
1414
|
+
# qux
|
1415
|
+
methods = @index.resolve_method("qux", "Bar")
|
1416
|
+
refute_nil(methods)
|
1417
|
+
|
1418
|
+
entry = T.must(methods.first)
|
1419
|
+
assert_kind_of(Entry::MethodAlias, entry)
|
1420
|
+
assert_equal("hello", entry.target.name)
|
1421
|
+
assert_equal("Bar", T.must(entry.target.owner).name)
|
1422
|
+
|
1423
|
+
# double
|
1424
|
+
methods = @index.resolve_method("double", "Bar")
|
1425
|
+
refute_nil(methods)
|
1426
|
+
|
1427
|
+
entry = T.must(methods.first)
|
1428
|
+
assert_kind_of(Entry::MethodAlias, entry)
|
1429
|
+
|
1430
|
+
target = entry.target
|
1431
|
+
assert_equal("double_alias", target.name)
|
1432
|
+
assert_kind_of(Entry::MethodAlias, target)
|
1433
|
+
assert_equal("Foo", T.must(target.owner).name)
|
1434
|
+
|
1435
|
+
final_target = target.target
|
1436
|
+
assert_equal("bar", final_target.name)
|
1437
|
+
assert_kind_of(Entry::Method, final_target)
|
1438
|
+
assert_equal("Foo", T.must(final_target.owner).name)
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
def test_resolving_circular_method_aliases
|
1442
|
+
index(<<~RUBY)
|
1443
|
+
class Foo
|
1444
|
+
alias bar bar
|
1445
|
+
end
|
1446
|
+
RUBY
|
1447
|
+
|
1448
|
+
# It's not possible to resolve an alias that points to itself
|
1449
|
+
methods = @index.resolve_method("bar", "Foo")
|
1450
|
+
assert_nil(methods)
|
1451
|
+
|
1452
|
+
entry = T.must(@index["bar"].first)
|
1453
|
+
assert_kind_of(Entry::UnresolvedMethodAlias, entry)
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
def test_unresolable_method_aliases
|
1457
|
+
index(<<~RUBY)
|
1458
|
+
class Foo
|
1459
|
+
alias bar baz
|
1460
|
+
end
|
1461
|
+
RUBY
|
1462
|
+
|
1463
|
+
# `baz` does not exist, so resolving `bar` is not possible
|
1464
|
+
methods = @index.resolve_method("bar", "Foo")
|
1465
|
+
assert_nil(methods)
|
1466
|
+
|
1467
|
+
entry = T.must(@index["bar"].first)
|
1468
|
+
assert_kind_of(Entry::UnresolvedMethodAlias, entry)
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
def test_only_aliases_for_the_right_owner_are_resolved
|
1472
|
+
index(<<~RUBY)
|
1473
|
+
class Foo
|
1474
|
+
attr_reader :name
|
1475
|
+
alias_method :decorated_name, :name
|
1476
|
+
end
|
1477
|
+
|
1478
|
+
class Bar
|
1479
|
+
alias_method :decorated_name, :to_s
|
1480
|
+
end
|
1481
|
+
RUBY
|
1482
|
+
|
1483
|
+
methods = @index.resolve_method("decorated_name", "Foo")
|
1484
|
+
refute_nil(methods)
|
1485
|
+
|
1486
|
+
entry = T.must(methods.first)
|
1487
|
+
assert_kind_of(Entry::MethodAlias, entry)
|
1488
|
+
|
1489
|
+
target = entry.target
|
1490
|
+
assert_equal("name", target.name)
|
1491
|
+
assert_kind_of(Entry::Accessor, target)
|
1492
|
+
assert_equal("Foo", T.must(target.owner).name)
|
1493
|
+
|
1494
|
+
other_decorated_name = T.must(@index["decorated_name"].find { |e| e.is_a?(Entry::UnresolvedMethodAlias) })
|
1495
|
+
assert_kind_of(Entry::UnresolvedMethodAlias, other_decorated_name)
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
def test_completion_does_not_include_unresolved_aliases
|
1499
|
+
index(<<~RUBY)
|
1500
|
+
class Foo
|
1501
|
+
alias_method :bar, :missing
|
1502
|
+
end
|
1503
|
+
RUBY
|
1504
|
+
|
1505
|
+
assert_empty(@index.method_completion_candidates("bar", "Foo"))
|
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
|
1176
1710
|
end
|
1177
1711
|
end
|