rubydex 0.3.0 → 0.4.0

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -7
  3. data/THIRD_PARTY_LICENSES.html +238 -2
  4. data/exe/rdx +2 -149
  5. data/ext/rubydex/config.c +140 -0
  6. data/ext/rubydex/config.h +16 -0
  7. data/ext/rubydex/diagnostic.c +75 -1
  8. data/ext/rubydex/diagnostic.h +2 -0
  9. data/ext/rubydex/graph.c +13 -45
  10. data/ext/rubydex/graph.h +6 -0
  11. data/ext/rubydex/query.c +398 -16
  12. data/ext/rubydex/rubydex.c +2 -0
  13. data/ext/rubydex/utils.c +11 -4
  14. data/lib/ruby_lsp/rubydex/addon.rb +211 -0
  15. data/lib/rubydex/cli/command/console.rb +55 -0
  16. data/lib/rubydex/cli/command/lint/explain.rb +74 -0
  17. data/lib/rubydex/cli/command/lint.rb +202 -0
  18. data/lib/rubydex/cli/command/mcp.rb +30 -0
  19. data/lib/rubydex/cli/command/query.rb +70 -0
  20. data/lib/rubydex/cli/command/skill.rb +69 -0
  21. data/lib/rubydex/cli/command.rb +168 -0
  22. data/lib/rubydex/cli.rb +93 -0
  23. data/lib/rubydex/config.rb +59 -0
  24. data/lib/rubydex/diagnostic.rb +12 -3
  25. data/lib/rubydex/errors.rb +42 -1
  26. data/lib/rubydex/graph.rb +10 -3
  27. data/lib/rubydex/linter/custom_rule.rb +97 -0
  28. data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
  29. data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
  30. data/lib/rubydex/linter/rule_loader.rb +36 -0
  31. data/lib/rubydex/linter/rule_test_case.rb +343 -0
  32. data/lib/rubydex/linter/runner.rb +56 -0
  33. data/lib/rubydex/linter.rb +19 -0
  34. data/lib/rubydex/location.rb +3 -0
  35. data/lib/rubydex/mcp_server.rb +1 -2
  36. data/lib/rubydex/related_information.rb +17 -0
  37. data/lib/rubydex/rule.rb +33 -0
  38. data/lib/rubydex/severity.rb +70 -0
  39. data/lib/rubydex/skill.rb +88 -0
  40. data/lib/rubydex/skill_registry.rb +62 -0
  41. data/lib/rubydex/version.rb +1 -1
  42. data/lib/rubydex.rb +6 -0
  43. data/lib/rubydex_linter/rules/rule_structure.rb +125 -0
  44. data/rbi/rubydex.rbi +558 -17
  45. data/rust/Cargo.lock +2 -2
  46. data/rust/rubydex/Cargo.toml +1 -1
  47. data/rust/rubydex/benches/graph_memory.rs +3 -5
  48. data/rust/rubydex/src/config.rs +538 -157
  49. data/rust/rubydex/src/diagnostic.rs +66 -40
  50. data/rust/rubydex/src/errors.rs +0 -1
  51. data/rust/rubydex/src/indexing/local_graph.rs +6 -5
  52. data/rust/rubydex/src/indexing/rbs_indexer.rs +270 -6
  53. data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -12
  54. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +134 -81
  55. data/rust/rubydex/src/lib.rs +1 -0
  56. data/rust/rubydex/src/listing.rs +26 -1
  57. data/rust/rubydex/src/main.rs +7 -4
  58. data/rust/rubydex/src/model/declaration.rs +302 -219
  59. data/rust/rubydex/src/model/graph.rs +27 -40
  60. data/rust/rubydex/src/model/name.rs +58 -17
  61. data/rust/rubydex/src/operation/ruby_builder.rs +30 -45
  62. data/rust/rubydex/src/path_helpers.rs +77 -0
  63. data/rust/rubydex/src/query/cypher/schema.rs +63 -0
  64. data/rust/rubydex/src/query/cypher/tests.rs +26 -1
  65. data/rust/rubydex/src/query/cypher.rs +8 -11
  66. data/rust/rubydex/src/query.rs +123 -43
  67. data/rust/rubydex/src/resolution.rs +139 -187
  68. data/rust/rubydex/src/resolution_tests.rs +247 -19
  69. data/rust/rubydex/src/test_utils/context.rs +2 -1
  70. data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
  71. data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
  72. data/rust/rubydex/tests/cli.rs +4 -4
  73. data/rust/rubydex-sys/src/config_api.rs +205 -0
  74. data/rust/rubydex-sys/src/cypher_api.rs +791 -0
  75. data/rust/rubydex-sys/src/diagnostic_api.rs +77 -8
  76. data/rust/rubydex-sys/src/graph_api.rs +13 -194
  77. data/rust/rubydex-sys/src/lib.rs +2 -0
  78. data/rust/rubydex-sys/src/name_api.rs +2 -6
  79. data/rust/rubydex-sys/src/utils.rs +37 -0
  80. data/skills/send-private-method/SKILL.md +133 -0
  81. metadata +31 -2
@@ -1,5 +1,5 @@
1
- use super::run_query;
2
1
  use super::schema::RelType;
2
+ use super::{render, run_query};
3
3
  use crate::model::graph::Graph;
4
4
  use crate::test_utils::GraphTest;
5
5
  use cypher_parser::{CypherValue, OutputFormat, ResultSet, execute, parse};
@@ -197,6 +197,31 @@ fn run_query_json_output() {
197
197
  assert_eq!(output, "[{\"c.name\":\"Dog\"}]");
198
198
  }
199
199
 
200
+ #[test]
201
+ fn render_formats_one_result_set_in_both_formats() {
202
+ // `execute` runs the query once; `render` formats that same result set as often as needed.
203
+ let graph = fixture_graph();
204
+ let result = run(&graph, "MATCH (c:Class {name: 'Dog'}) RETURN c.name");
205
+
206
+ assert_eq!(render(&result, OutputFormat::Json), "[{\"c.name\":\"Dog\"}]");
207
+
208
+ let table = render(&result, OutputFormat::Table);
209
+ assert!(table.contains("c.name"));
210
+ assert!(table.contains("Dog"));
211
+ assert!(table.contains("1 row"));
212
+ }
213
+
214
+ #[test]
215
+ fn incoming_declares_and_defines_reach_the_document() {
216
+ // Exercises `expand_in`: walk the Document -> Definition -> Declaration spine backwards.
217
+ let graph = fixture_graph();
218
+ let result = run(
219
+ &graph,
220
+ "MATCH (decl:Class {name: 'Dog'})<-[:DECLARES]-(def:Definition)<-[:DEFINES]-(d:Document) RETURN DISTINCT d.name",
221
+ );
222
+ assert_eq!(column_strings(&result, 0), vec!["zoo.rb".to_string()]);
223
+ }
224
+
200
225
  #[test]
201
226
  fn unknown_relationship_type_errors() {
202
227
  let graph = fixture_graph();
@@ -18,8 +18,9 @@
18
18
  // `Graph` (in `schema`) and the static schema description (in `schema_info`).
19
19
  //
20
20
  // `Query` is the opaque parsed-query object: callers can `parse` a query string once (failing fast
21
- // on syntax errors), then `run_parsed` it against a graph that was built afterwards.
22
- pub use cypher_parser::{CypherError, OutputFormat, Query, parse};
21
+ // on syntax errors), `execute` it against a graph that was built afterwards, and `render` the
22
+ // resulting [`ResultSet`] without running the query again.
23
+ pub use cypher_parser::{CypherError, CypherValue, OutputFormat, Query, ResultSet, execute, parse};
23
24
 
24
25
  pub mod schema;
25
26
  pub mod schema_info;
@@ -35,15 +36,11 @@ pub fn run_query(graph: &Graph, query: &str, output_format: OutputFormat) -> Res
35
36
  cypher_parser::run_query(graph, query, output_format)
36
37
  }
37
38
 
38
- /// Executes an already-parsed [`Query`] against the graph and formats the result. Pair with
39
- /// [`parse`] to validate a query before building the graph.
40
- ///
41
- /// # Errors
42
- ///
43
- /// Returns a [`CypherError`] if the query cannot be executed.
44
- pub fn run_parsed(graph: &Graph, query: &Query, output_format: OutputFormat) -> Result<String, CypherError> {
45
- let result = cypher_parser::execute(graph, query)?;
46
- Ok(cypher_parser::format::format(&result, output_format))
39
+ /// Renders an already-executed [`ResultSet`] in the requested format. Pair with [`execute`] to run a
40
+ /// parsed query once and render its result set as often as needed.
41
+ #[must_use]
42
+ pub fn render(result: &ResultSet, output_format: OutputFormat) -> String {
43
+ cypher_parser::format::format(result, output_format)
47
44
  }
48
45
 
49
46
  /// Returns a description of the queryable schema (node labels, relationship types, and properties)
@@ -1173,7 +1173,13 @@ mod tests {
1173
1173
  );
1174
1174
  context.resolve();
1175
1175
 
1176
- let name_id = Name::new(StringId::from("Child"), ParentScope::None, None).id();
1176
+ let name_id = Name::new(
1177
+ context.graph().names(),
1178
+ StringId::from("Child"),
1179
+ ParentScope::None,
1180
+ None,
1181
+ )
1182
+ .id();
1177
1183
  assert_declaration_completion_eq!(
1178
1184
  context,
1179
1185
  CompletionReceiver::Expression {
@@ -1222,7 +1228,13 @@ mod tests {
1222
1228
  );
1223
1229
  context.resolve();
1224
1230
 
1225
- let name_id = Name::new(StringId::from("Child"), ParentScope::None, None).id();
1231
+ let name_id = Name::new(
1232
+ context.graph().names(),
1233
+ StringId::from("Child"),
1234
+ ParentScope::None,
1235
+ None,
1236
+ )
1237
+ .id();
1226
1238
  assert_declaration_completion_eq!(
1227
1239
  context,
1228
1240
  CompletionReceiver::Expression {
@@ -1271,7 +1283,7 @@ mod tests {
1271
1283
  );
1272
1284
  context.resolve();
1273
1285
 
1274
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
1286
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
1275
1287
  assert_declaration_completion_eq!(
1276
1288
  context,
1277
1289
  CompletionReceiver::Expression {
@@ -1320,8 +1332,14 @@ mod tests {
1320
1332
  );
1321
1333
  context.resolve();
1322
1334
 
1323
- let foo_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
1324
- let name_id = Name::new(StringId::from("<Foo>"), ParentScope::Attached(foo_id), Some(foo_id)).id();
1335
+ let foo_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
1336
+ let name_id = Name::new(
1337
+ context.graph().names(),
1338
+ StringId::from("<Foo>"),
1339
+ ParentScope::Attached(foo_id),
1340
+ Some(foo_id),
1341
+ )
1342
+ .id();
1325
1343
  assert_declaration_completion_eq!(
1326
1344
  context,
1327
1345
  CompletionReceiver::Expression {
@@ -1341,7 +1359,7 @@ mod tests {
1341
1359
  ]
1342
1360
  );
1343
1361
 
1344
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
1362
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
1345
1363
  assert_declaration_completion_eq!(
1346
1364
  context,
1347
1365
  CompletionReceiver::Expression {
@@ -1383,8 +1401,14 @@ mod tests {
1383
1401
  );
1384
1402
  context.resolve();
1385
1403
 
1386
- let foo_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
1387
- let name_id = Name::new(StringId::from("<Foo>"), ParentScope::Attached(foo_id), Some(foo_id)).id();
1404
+ let foo_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
1405
+ let name_id = Name::new(
1406
+ context.graph().names(),
1407
+ StringId::from("<Foo>"),
1408
+ ParentScope::Attached(foo_id),
1409
+ Some(foo_id),
1410
+ )
1411
+ .id();
1388
1412
 
1389
1413
  assert_declaration_completion_eq!(
1390
1414
  context,
@@ -1431,9 +1455,10 @@ mod tests {
1431
1455
  context.resolve();
1432
1456
 
1433
1457
  let name_id = Name::new(
1458
+ context.graph().names(),
1434
1459
  StringId::from("Bar"),
1435
1460
  ParentScope::TopLevel,
1436
- Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
1461
+ Some(Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id()),
1437
1462
  )
1438
1463
  .id();
1439
1464
 
@@ -1457,7 +1482,7 @@ mod tests {
1457
1482
  ]
1458
1483
  );
1459
1484
 
1460
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
1485
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
1461
1486
  assert_declaration_completion_eq!(
1462
1487
  context,
1463
1488
  CompletionReceiver::Expression {
@@ -1498,8 +1523,14 @@ mod tests {
1498
1523
  );
1499
1524
  context.resolve();
1500
1525
 
1501
- let foo_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
1502
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, Some(foo_id)).id();
1526
+ let foo_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
1527
+ let name_id = Name::new(
1528
+ context.graph().names(),
1529
+ StringId::from("Bar"),
1530
+ ParentScope::None,
1531
+ Some(foo_id),
1532
+ )
1533
+ .id();
1503
1534
  // Foo::CONST is reachable from Foo::Bar through lexical scoping, so it must appear as a completion candidate
1504
1535
  // when the user types the unqualified name CONST
1505
1536
  assert_declaration_completion_eq!(
@@ -1544,9 +1575,10 @@ mod tests {
1544
1575
  context.resolve();
1545
1576
 
1546
1577
  let name_id = Name::new(
1578
+ context.graph().names(),
1547
1579
  StringId::from("Bar"),
1548
1580
  ParentScope::None,
1549
- Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
1581
+ Some(Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id()),
1550
1582
  )
1551
1583
  .id();
1552
1584
  assert_declaration_completion_eq!(
@@ -2078,7 +2110,7 @@ mod tests {
2078
2110
  );
2079
2111
  context.resolve();
2080
2112
 
2081
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2113
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2082
2114
  assert_declaration_completion_eq!(
2083
2115
  context,
2084
2116
  CompletionReceiver::MethodArgument {
@@ -2119,7 +2151,7 @@ mod tests {
2119
2151
  );
2120
2152
  context.resolve();
2121
2153
 
2122
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2154
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2123
2155
  assert_declaration_completion_eq!(
2124
2156
  context,
2125
2157
  CompletionReceiver::MethodArgument {
@@ -2156,7 +2188,7 @@ mod tests {
2156
2188
  );
2157
2189
  context.resolve();
2158
2190
 
2159
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2191
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2160
2192
  assert_declaration_completion_eq!(
2161
2193
  context,
2162
2194
  CompletionReceiver::MethodArgument {
@@ -2182,7 +2214,7 @@ mod tests {
2182
2214
  );
2183
2215
  context.resolve();
2184
2216
 
2185
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2217
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2186
2218
  assert_declaration_completion_eq!(
2187
2219
  context,
2188
2220
  CompletionReceiver::MethodArgument {
@@ -2226,7 +2258,7 @@ mod tests {
2226
2258
  );
2227
2259
  context.resolve();
2228
2260
 
2229
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2261
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2230
2262
  assert_declaration_completion_eq!(
2231
2263
  context,
2232
2264
  CompletionReceiver::MethodArgument {
@@ -2254,7 +2286,7 @@ mod tests {
2254
2286
  context.index_uri("file:///foo.rb", "class Foo; end");
2255
2287
  context.resolve();
2256
2288
 
2257
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2289
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2258
2290
  assert_completion_eq!(
2259
2291
  context,
2260
2292
  CompletionReceiver::Expression {
@@ -2319,7 +2351,7 @@ mod tests {
2319
2351
  context.index_uri("file:///foo.rb", "class Foo; def bar(name:); end; end");
2320
2352
  context.resolve();
2321
2353
 
2322
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2354
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2323
2355
  assert_completion_eq!(
2324
2356
  context,
2325
2357
  CompletionReceiver::MethodArgument {
@@ -2440,7 +2472,13 @@ mod tests {
2440
2472
  );
2441
2473
  context.resolve();
2442
2474
 
2443
- let outer_name_id = Name::new(StringId::from("Outer"), ParentScope::None, None).id();
2475
+ let outer_name_id = Name::new(
2476
+ context.graph().names(),
2477
+ StringId::from("Outer"),
2478
+ ParentScope::None,
2479
+ None,
2480
+ )
2481
+ .id();
2444
2482
  assert_declaration_completion_eq!(
2445
2483
  context,
2446
2484
  CompletionReceiver::Expression {
@@ -2479,7 +2517,13 @@ mod tests {
2479
2517
  );
2480
2518
  context.resolve();
2481
2519
 
2482
- let name_id = Name::new(StringId::from("Outer"), ParentScope::None, None).id();
2520
+ let name_id = Name::new(
2521
+ context.graph().names(),
2522
+ StringId::from("Outer"),
2523
+ ParentScope::None,
2524
+ None,
2525
+ )
2526
+ .id();
2483
2527
  // `self_decl_id` points to the alias `Outer::MyAlias`, which is a `ConstantAlias` rather than a `Namespace`.
2484
2528
  // The completion should still collect members from the aliased namespace (`Outer::Original`) instead of
2485
2529
  // returning an error, so callers do not have to unwrap aliases themselves.
@@ -2525,7 +2569,7 @@ mod tests {
2525
2569
  );
2526
2570
  context.resolve();
2527
2571
 
2528
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
2572
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
2529
2573
  assert_declaration_completion_eq!(
2530
2574
  context,
2531
2575
  CompletionReceiver::Expression {
@@ -2568,7 +2612,7 @@ mod tests {
2568
2612
  );
2569
2613
  context.resolve();
2570
2614
 
2571
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
2615
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
2572
2616
  assert_declaration_completion_eq!(
2573
2617
  context,
2574
2618
  CompletionReceiver::Expression {
@@ -2613,7 +2657,7 @@ mod tests {
2613
2657
  );
2614
2658
  context.resolve();
2615
2659
 
2616
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
2660
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
2617
2661
  assert_declaration_completion_eq!(
2618
2662
  context,
2619
2663
  CompletionReceiver::Expression {
@@ -2650,7 +2694,13 @@ mod tests {
2650
2694
  );
2651
2695
  context.resolve();
2652
2696
 
2653
- let name_id = Name::new(StringId::from("Object"), ParentScope::None, None).id();
2697
+ let name_id = Name::new(
2698
+ context.graph().names(),
2699
+ StringId::from("Object"),
2700
+ ParentScope::None,
2701
+ None,
2702
+ )
2703
+ .id();
2654
2704
  assert_declaration_completion_eq!(
2655
2705
  context,
2656
2706
  CompletionReceiver::Expression {
@@ -2677,7 +2727,7 @@ mod tests {
2677
2727
  );
2678
2728
  context.resolve();
2679
2729
 
2680
- let name_id = Name::new(StringId::from("Mod"), ParentScope::None, None).id();
2730
+ let name_id = Name::new(context.graph().names(), StringId::from("Mod"), ParentScope::None, None).id();
2681
2731
  assert_declaration_completion_eq!(
2682
2732
  context,
2683
2733
  CompletionReceiver::Expression {
@@ -2715,7 +2765,7 @@ mod tests {
2715
2765
  );
2716
2766
  context.resolve();
2717
2767
 
2718
- let name_id = Name::new(StringId::from("Mod"), ParentScope::None, None).id();
2768
+ let name_id = Name::new(context.graph().names(), StringId::from("Mod"), ParentScope::None, None).id();
2719
2769
  assert_declaration_completion_eq!(
2720
2770
  context,
2721
2771
  CompletionReceiver::Expression {
@@ -2750,7 +2800,13 @@ mod tests {
2750
2800
  );
2751
2801
  context.resolve();
2752
2802
 
2753
- let name_id = Name::new(StringId::from("Object"), ParentScope::None, None).id();
2803
+ let name_id = Name::new(
2804
+ context.graph().names(),
2805
+ StringId::from("Object"),
2806
+ ParentScope::None,
2807
+ None,
2808
+ )
2809
+ .id();
2754
2810
  assert_declaration_completion_eq!(
2755
2811
  context,
2756
2812
  CompletionReceiver::Expression {
@@ -2785,7 +2841,7 @@ mod tests {
2785
2841
  );
2786
2842
  context.resolve();
2787
2843
 
2788
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
2844
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
2789
2845
  assert_declaration_completion_eq!(
2790
2846
  context,
2791
2847
  CompletionReceiver::Expression {
@@ -2818,9 +2874,21 @@ mod tests {
2818
2874
  );
2819
2875
  context.resolve();
2820
2876
 
2821
- let bar_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
2822
- let foo_ref_id = Name::new(StringId::from("Foo"), ParentScope::None, Some(bar_id)).id();
2823
- let nesting_name_id = Name::new(StringId::from("<Foo>"), ParentScope::Attached(foo_ref_id), Some(bar_id)).id();
2877
+ let bar_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
2878
+ let foo_ref_id = Name::new(
2879
+ context.graph().names(),
2880
+ StringId::from("Foo"),
2881
+ ParentScope::None,
2882
+ Some(bar_id),
2883
+ )
2884
+ .id();
2885
+ let nesting_name_id = Name::new(
2886
+ context.graph().names(),
2887
+ StringId::from("<Foo>"),
2888
+ ParentScope::Attached(foo_ref_id),
2889
+ Some(bar_id),
2890
+ )
2891
+ .id();
2824
2892
 
2825
2893
  assert_declaration_completion_eq!(
2826
2894
  context,
@@ -2859,7 +2927,7 @@ mod tests {
2859
2927
  );
2860
2928
  context.resolve();
2861
2929
 
2862
- let name_id = Name::new(StringId::from("Mod"), ParentScope::None, None).id();
2930
+ let name_id = Name::new(context.graph().names(), StringId::from("Mod"), ParentScope::None, None).id();
2863
2931
  assert_declaration_completion_eq!(
2864
2932
  context,
2865
2933
  CompletionReceiver::Expression {
@@ -2897,8 +2965,14 @@ mod tests {
2897
2965
  );
2898
2966
  context.resolve();
2899
2967
 
2900
- let foo_ref_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
2901
- let nesting_name_id = Name::new(StringId::from("<Foo>"), ParentScope::Attached(foo_ref_id), None).id();
2968
+ let foo_ref_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2969
+ let nesting_name_id = Name::new(
2970
+ context.graph().names(),
2971
+ StringId::from("<Foo>"),
2972
+ ParentScope::Attached(foo_ref_id),
2973
+ None,
2974
+ )
2975
+ .id();
2902
2976
 
2903
2977
  assert_declaration_completion_eq!(
2904
2978
  context,
@@ -2923,7 +2997,7 @@ mod tests {
2923
2997
  );
2924
2998
  context.resolve();
2925
2999
 
2926
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
3000
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2927
3001
  let result = completion_candidates(
2928
3002
  context.graph(),
2929
3003
  CompletionContext::new(CompletionReceiver::Expression {
@@ -2949,7 +3023,7 @@ mod tests {
2949
3023
  );
2950
3024
  context.resolve();
2951
3025
 
2952
- let name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
3026
+ let name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
2953
3027
  let result = completion_candidates(
2954
3028
  context.graph(),
2955
3029
  CompletionContext::new(CompletionReceiver::Expression {
@@ -2981,7 +3055,13 @@ mod tests {
2981
3055
  );
2982
3056
  context.resolve();
2983
3057
 
2984
- let name_id = Name::new(StringId::from("Outer"), ParentScope::None, None).id();
3058
+ let name_id = Name::new(
3059
+ context.graph().names(),
3060
+ StringId::from("Outer"),
3061
+ ParentScope::None,
3062
+ None,
3063
+ )
3064
+ .id();
2985
3065
  assert_declaration_completion_eq!(
2986
3066
  context,
2987
3067
  CompletionReceiver::Expression {
@@ -3024,7 +3104,7 @@ mod tests {
3024
3104
  );
3025
3105
  context.resolve();
3026
3106
 
3027
- let name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
3107
+ let name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
3028
3108
  assert_declaration_completion_eq!(
3029
3109
  context,
3030
3110
  CompletionReceiver::Expression {
@@ -3097,7 +3177,7 @@ mod tests {
3097
3177
  );
3098
3178
  context.resolve();
3099
3179
 
3100
- let foo_name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
3180
+ let foo_name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
3101
3181
  assert_declaration_completion_eq!(
3102
3182
  context,
3103
3183
  CompletionReceiver::Expression {
@@ -3117,7 +3197,7 @@ mod tests {
3117
3197
  ]
3118
3198
  );
3119
3199
 
3120
- let bar_name_id = Name::new(StringId::from("Bar"), ParentScope::None, None).id();
3200
+ let bar_name_id = Name::new(context.graph().names(), StringId::from("Bar"), ParentScope::None, None).id();
3121
3201
  assert_declaration_completion_eq!(
3122
3202
  context,
3123
3203
  CompletionReceiver::Expression {
@@ -3433,7 +3513,7 @@ mod tests {
3433
3513
  );
3434
3514
  context.resolve();
3435
3515
 
3436
- let foo_name_id = Name::new(StringId::from("Foo"), ParentScope::None, None).id();
3516
+ let foo_name_id = Name::new(context.graph().names(), StringId::from("Foo"), ParentScope::None, None).id();
3437
3517
  assert_declaration_completion_eq!(
3438
3518
  context,
3439
3519
  CompletionReceiver::Expression {