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.
- checksums.yaml +4 -4
- data/README.md +45 -7
- data/THIRD_PARTY_LICENSES.html +238 -2
- data/exe/rdx +2 -149
- data/ext/rubydex/config.c +140 -0
- data/ext/rubydex/config.h +16 -0
- data/ext/rubydex/diagnostic.c +75 -1
- data/ext/rubydex/diagnostic.h +2 -0
- data/ext/rubydex/graph.c +13 -45
- data/ext/rubydex/graph.h +6 -0
- data/ext/rubydex/query.c +398 -16
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/utils.c +11 -4
- data/lib/ruby_lsp/rubydex/addon.rb +211 -0
- data/lib/rubydex/cli/command/console.rb +55 -0
- data/lib/rubydex/cli/command/lint/explain.rb +74 -0
- data/lib/rubydex/cli/command/lint.rb +202 -0
- data/lib/rubydex/cli/command/mcp.rb +30 -0
- data/lib/rubydex/cli/command/query.rb +70 -0
- data/lib/rubydex/cli/command/skill.rb +69 -0
- data/lib/rubydex/cli/command.rb +168 -0
- data/lib/rubydex/cli.rb +93 -0
- data/lib/rubydex/config.rb +59 -0
- data/lib/rubydex/diagnostic.rb +12 -3
- data/lib/rubydex/errors.rb +42 -1
- data/lib/rubydex/graph.rb +10 -3
- data/lib/rubydex/linter/custom_rule.rb +97 -0
- data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
- data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
- data/lib/rubydex/linter/rule_loader.rb +36 -0
- data/lib/rubydex/linter/rule_test_case.rb +343 -0
- data/lib/rubydex/linter/runner.rb +56 -0
- data/lib/rubydex/linter.rb +19 -0
- data/lib/rubydex/location.rb +3 -0
- data/lib/rubydex/mcp_server.rb +1 -2
- data/lib/rubydex/related_information.rb +17 -0
- data/lib/rubydex/rule.rb +33 -0
- data/lib/rubydex/severity.rb +70 -0
- data/lib/rubydex/skill.rb +88 -0
- data/lib/rubydex/skill_registry.rb +62 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +6 -0
- data/lib/rubydex_linter/rules/rule_structure.rb +125 -0
- data/rbi/rubydex.rbi +558 -17
- data/rust/Cargo.lock +2 -2
- data/rust/rubydex/Cargo.toml +1 -1
- data/rust/rubydex/benches/graph_memory.rs +3 -5
- data/rust/rubydex/src/config.rs +538 -157
- data/rust/rubydex/src/diagnostic.rs +66 -40
- data/rust/rubydex/src/errors.rs +0 -1
- data/rust/rubydex/src/indexing/local_graph.rs +6 -5
- data/rust/rubydex/src/indexing/rbs_indexer.rs +270 -6
- data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -12
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +134 -81
- data/rust/rubydex/src/lib.rs +1 -0
- data/rust/rubydex/src/listing.rs +26 -1
- data/rust/rubydex/src/main.rs +7 -4
- data/rust/rubydex/src/model/declaration.rs +302 -219
- data/rust/rubydex/src/model/graph.rs +27 -40
- data/rust/rubydex/src/model/name.rs +58 -17
- data/rust/rubydex/src/operation/ruby_builder.rs +30 -45
- data/rust/rubydex/src/path_helpers.rs +77 -0
- data/rust/rubydex/src/query/cypher/schema.rs +63 -0
- data/rust/rubydex/src/query/cypher/tests.rs +26 -1
- data/rust/rubydex/src/query/cypher.rs +8 -11
- data/rust/rubydex/src/query.rs +123 -43
- data/rust/rubydex/src/resolution.rs +139 -187
- data/rust/rubydex/src/resolution_tests.rs +247 -19
- data/rust/rubydex/src/test_utils/context.rs +2 -1
- data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
- data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
- data/rust/rubydex/tests/cli.rs +4 -4
- data/rust/rubydex-sys/src/config_api.rs +205 -0
- data/rust/rubydex-sys/src/cypher_api.rs +791 -0
- data/rust/rubydex-sys/src/diagnostic_api.rs +77 -8
- data/rust/rubydex-sys/src/graph_api.rs +13 -194
- data/rust/rubydex-sys/src/lib.rs +2 -0
- data/rust/rubydex-sys/src/name_api.rs +2 -6
- data/rust/rubydex-sys/src/utils.rs +37 -0
- data/skills/send-private-method/SKILL.md +133 -0
- metadata +31 -2
|
@@ -6,6 +6,7 @@ use crate::{
|
|
|
6
6
|
assert_def_comments_eq, assert_def_mixins_eq, assert_def_name_eq, assert_def_name_offset_eq, assert_def_str_eq,
|
|
7
7
|
assert_def_superclass_ref_eq, assert_definition_at, assert_dependents, assert_local_diagnostics_eq,
|
|
8
8
|
assert_method_has_receiver, assert_name_path_eq, assert_no_local_diagnostics, assert_string_eq,
|
|
9
|
+
diagnostic::Severity,
|
|
9
10
|
model::{
|
|
10
11
|
definitions::{Definition, Parameter, Receiver, Signatures},
|
|
11
12
|
ids::{StringId, UriId},
|
|
@@ -967,7 +968,8 @@ mod class_and_module_tests {
|
|
|
967
968
|
|
|
968
969
|
assert_local_diagnostics_eq!(
|
|
969
970
|
&context,
|
|
970
|
-
["
|
|
971
|
+
["DynamicConstantReference: Dynamic constant reference (1:7-1:10)"],
|
|
972
|
+
severity: Severity::Information
|
|
971
973
|
);
|
|
972
974
|
assert!(context.graph().definitions().is_empty());
|
|
973
975
|
}
|
|
@@ -1071,7 +1073,7 @@ mod class_and_module_tests {
|
|
|
1071
1073
|
|
|
1072
1074
|
assert_local_diagnostics_eq!(
|
|
1073
1075
|
&context,
|
|
1074
|
-
["
|
|
1076
|
+
["DynamicConstantReference: Dynamic constant reference (1:8-1:11)"]
|
|
1075
1077
|
);
|
|
1076
1078
|
assert!(context.graph().definitions().is_empty());
|
|
1077
1079
|
}
|
|
@@ -1173,7 +1175,7 @@ mod method_tests {
|
|
|
1173
1175
|
|
|
1174
1176
|
assert_local_diagnostics_eq!(
|
|
1175
1177
|
&context,
|
|
1176
|
-
["
|
|
1178
|
+
["DynamicSingletonDefinition: Dynamic receiver for singleton method definition (1:1-1:17)"]
|
|
1177
1179
|
);
|
|
1178
1180
|
assert_eq!(context.graph().definitions().len(), 0);
|
|
1179
1181
|
assert_method_references_eq!(&context, ["foo"]);
|
|
@@ -1416,7 +1418,7 @@ mod singleton_class_tests {
|
|
|
1416
1418
|
|
|
1417
1419
|
assert_local_diagnostics_eq!(
|
|
1418
1420
|
&context,
|
|
1419
|
-
["
|
|
1421
|
+
["DynamicSingletonDefinition: Dynamic singleton class definition (1:1-3:4)"]
|
|
1420
1422
|
);
|
|
1421
1423
|
assert_eq!(context.graph().definitions().len(), 0);
|
|
1422
1424
|
}
|
|
@@ -1557,6 +1559,34 @@ mod visibility_tests {
|
|
|
1557
1559
|
});
|
|
1558
1560
|
}
|
|
1559
1561
|
|
|
1562
|
+
#[test]
|
|
1563
|
+
fn index_module_function_with_body() {
|
|
1564
|
+
let context = index_source({
|
|
1565
|
+
"
|
|
1566
|
+
module Foo
|
|
1567
|
+
module_function
|
|
1568
|
+
|
|
1569
|
+
def bar
|
|
1570
|
+
@value = CONST
|
|
1571
|
+
baz(1)
|
|
1572
|
+
end
|
|
1573
|
+
end
|
|
1574
|
+
"
|
|
1575
|
+
});
|
|
1576
|
+
|
|
1577
|
+
assert_no_local_diagnostics!(&context);
|
|
1578
|
+
assert_eq!(context.graph().definitions().len(), 4);
|
|
1579
|
+
assert_eq!(context.graph().document().definitions().len(), 4);
|
|
1580
|
+
assert_eq!(context.graph().document().constant_references().len(), 1);
|
|
1581
|
+
assert_eq!(context.graph().document().method_references().len(), 1);
|
|
1582
|
+
assert_constant_references_eq!(&context, ["CONST"]);
|
|
1583
|
+
assert_method_references_eq!(&context, ["baz"]);
|
|
1584
|
+
|
|
1585
|
+
let methods = context.all_definitions_at("4:3-7:6");
|
|
1586
|
+
assert_eq!(methods.len(), 2);
|
|
1587
|
+
assert_definition_at!(&context, "5:5-5:11", InstanceVariable);
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1560
1590
|
#[test]
|
|
1561
1591
|
fn index_def_node_with_visibility_nested() {
|
|
1562
1592
|
let context = index_source({
|
|
@@ -1772,12 +1802,13 @@ mod visibility_tests {
|
|
|
1772
1802
|
assert_local_diagnostics_eq!(
|
|
1773
1803
|
&context,
|
|
1774
1804
|
vec![
|
|
1775
|
-
"
|
|
1776
|
-
"
|
|
1777
|
-
"
|
|
1778
|
-
"
|
|
1779
|
-
"
|
|
1780
|
-
]
|
|
1805
|
+
"InvalidConstantVisibility: `private_constant` called at top level (1:1-1:22)",
|
|
1806
|
+
"InvalidConstantVisibility: `private_constant` called at top level (2:1-2:27)",
|
|
1807
|
+
"InvalidConstantVisibility: Dynamic receiver for `private_constant` (3:1-3:4)",
|
|
1808
|
+
"InvalidConstantVisibility: `private_constant` called with a non-literal argument (6:20-6:29)",
|
|
1809
|
+
"InvalidConstantVisibility: `private_constant` called with a non-literal argument (6:31-6:42)",
|
|
1810
|
+
],
|
|
1811
|
+
severity: Severity::Warning
|
|
1781
1812
|
);
|
|
1782
1813
|
|
|
1783
1814
|
assert_eq!(context.graph().definitions().len(), 3); // Foo, Foo.qux, Foo#foo
|
|
@@ -1809,11 +1840,11 @@ mod visibility_tests {
|
|
|
1809
1840
|
assert_local_diagnostics_eq!(
|
|
1810
1841
|
&context,
|
|
1811
1842
|
vec![
|
|
1812
|
-
"
|
|
1813
|
-
"
|
|
1814
|
-
"
|
|
1815
|
-
"
|
|
1816
|
-
"
|
|
1843
|
+
"InvalidConstantVisibility: `public_constant` called at top level (1:1-1:21)",
|
|
1844
|
+
"InvalidConstantVisibility: `public_constant` called at top level (2:1-2:26)",
|
|
1845
|
+
"InvalidConstantVisibility: Dynamic receiver for `public_constant` (3:1-3:4)",
|
|
1846
|
+
"InvalidConstantVisibility: `public_constant` called with a non-literal argument (6:19-6:28)",
|
|
1847
|
+
"InvalidConstantVisibility: `public_constant` called with a non-literal argument (6:30-6:41)",
|
|
1817
1848
|
]
|
|
1818
1849
|
);
|
|
1819
1850
|
|
|
@@ -1890,7 +1921,7 @@ mod visibility_tests {
|
|
|
1890
1921
|
|
|
1891
1922
|
assert_local_diagnostics_eq!(
|
|
1892
1923
|
&context,
|
|
1893
|
-
vec!["
|
|
1924
|
+
vec!["InvalidMethodVisibility: `private` called with a non-literal argument (4:17-4:27)"]
|
|
1894
1925
|
);
|
|
1895
1926
|
|
|
1896
1927
|
// :foo is a literal arg, so visibility is still applied
|
|
@@ -1916,7 +1947,7 @@ mod visibility_tests {
|
|
|
1916
1947
|
|
|
1917
1948
|
assert_local_diagnostics_eq!(
|
|
1918
1949
|
&context,
|
|
1919
|
-
vec!["
|
|
1950
|
+
vec!["InvalidMethodVisibility: `private` cannot be called with an explicit receiver (4:3-4:19)"]
|
|
1920
1951
|
);
|
|
1921
1952
|
|
|
1922
1953
|
for def in context.graph().definitions().values() {
|
|
@@ -1941,7 +1972,7 @@ mod visibility_tests {
|
|
|
1941
1972
|
|
|
1942
1973
|
assert_local_diagnostics_eq!(
|
|
1943
1974
|
&context,
|
|
1944
|
-
vec!["
|
|
1975
|
+
vec!["InvalidMethodVisibility: `private` called with a non-literal argument (4:11-4:21)"]
|
|
1945
1976
|
);
|
|
1946
1977
|
|
|
1947
1978
|
// No MethodVisibilityDefinition created
|
|
@@ -1965,7 +1996,7 @@ mod visibility_tests {
|
|
|
1965
1996
|
|
|
1966
1997
|
assert_local_diagnostics_eq!(
|
|
1967
1998
|
&context,
|
|
1968
|
-
vec!["
|
|
1999
|
+
vec!["InvalidMethodVisibility: `private` called with a non-literal argument (2:11-2:23)"]
|
|
1969
2000
|
);
|
|
1970
2001
|
|
|
1971
2002
|
// No MethodVisibilityDefinition created
|
|
@@ -1989,7 +2020,7 @@ mod visibility_tests {
|
|
|
1989
2020
|
|
|
1990
2021
|
assert_local_diagnostics_eq!(
|
|
1991
2022
|
&context,
|
|
1992
|
-
vec!["
|
|
2023
|
+
vec!["InvalidMethodVisibility: `private` called with a non-literal argument (2:11-2:35)"]
|
|
1993
2024
|
);
|
|
1994
2025
|
|
|
1995
2026
|
// No MethodVisibilityDefinition or AttrReader created from that call
|
|
@@ -2032,9 +2063,7 @@ mod visibility_tests {
|
|
|
2032
2063
|
// attr_reader(:foo) returns an array in multi-arg context, invalid for `private`
|
|
2033
2064
|
assert_local_diagnostics_eq!(
|
|
2034
2065
|
&context,
|
|
2035
|
-
vec![
|
|
2036
|
-
"invalid-method-visibility: `private` with `attr_*` is only supported as a single argument (2:11-2:28)"
|
|
2037
|
-
]
|
|
2066
|
+
vec!["InvalidMethodVisibility: `private` with `attr_*` is only supported as a single argument (2:11-2:28)"]
|
|
2038
2067
|
);
|
|
2039
2068
|
|
|
2040
2069
|
// foo reader still defined via side effects, but public
|
|
@@ -2097,7 +2126,7 @@ mod visibility_tests {
|
|
|
2097
2126
|
|
|
2098
2127
|
assert_local_diagnostics_eq!(
|
|
2099
2128
|
&context,
|
|
2100
|
-
vec!["
|
|
2129
|
+
vec!["InvalidMethodVisibility: `module_function` can only be used in modules (4:3-4:23)"]
|
|
2101
2130
|
);
|
|
2102
2131
|
|
|
2103
2132
|
for def in context.graph().definitions().values() {
|
|
@@ -2169,8 +2198,8 @@ mod visibility_tests {
|
|
|
2169
2198
|
assert_local_diagnostics_eq!(
|
|
2170
2199
|
&context,
|
|
2171
2200
|
vec![
|
|
2172
|
-
"
|
|
2173
|
-
"
|
|
2201
|
+
"InvalidMethodVisibility: `private` called with a non-literal argument (2:25-2:32)",
|
|
2202
|
+
"InvalidMethodVisibility: `private` called with a non-literal argument (3:11-3:18)",
|
|
2174
2203
|
]
|
|
2175
2204
|
);
|
|
2176
2205
|
|
|
@@ -2200,8 +2229,8 @@ mod visibility_tests {
|
|
|
2200
2229
|
assert_local_diagnostics_eq!(
|
|
2201
2230
|
&context,
|
|
2202
2231
|
vec![
|
|
2203
|
-
"
|
|
2204
|
-
"
|
|
2232
|
+
"InvalidMethodVisibility: `private` called with a non-literal argument (2:11-2:18)",
|
|
2233
|
+
"InvalidMethodVisibility: `private` called with a non-literal argument (2:20-2:27)",
|
|
2205
2234
|
]
|
|
2206
2235
|
);
|
|
2207
2236
|
|
|
@@ -2221,7 +2250,7 @@ mod visibility_tests {
|
|
|
2221
2250
|
// module_function in a class is always invalid regardless of args
|
|
2222
2251
|
assert_local_diagnostics_eq!(
|
|
2223
2252
|
&context,
|
|
2224
|
-
vec!["
|
|
2253
|
+
vec!["InvalidMethodVisibility: `module_function` can only be used in modules (2:3-2:37)"]
|
|
2225
2254
|
);
|
|
2226
2255
|
|
|
2227
2256
|
for def in context.graph().definitions().values() {
|
|
@@ -2307,12 +2336,13 @@ mod visibility_tests {
|
|
|
2307
2336
|
assert_local_diagnostics_eq!(
|
|
2308
2337
|
&context,
|
|
2309
2338
|
vec![
|
|
2310
|
-
"
|
|
2311
|
-
"
|
|
2312
|
-
"
|
|
2313
|
-
"
|
|
2314
|
-
"
|
|
2315
|
-
]
|
|
2339
|
+
"InvalidMethodVisibility: `private_class_method` called at top level (1:1-1:34)",
|
|
2340
|
+
"InvalidMethodVisibility: `private_class_method` called at top level (2:1-2:39)",
|
|
2341
|
+
"InvalidMethodVisibility: `private_class_method` called with a non-literal argument (6:24-6:35)",
|
|
2342
|
+
"InvalidMethodVisibility: `private_class_method` does not accept `attr_*` arguments (8:24-8:41)",
|
|
2343
|
+
"InvalidMethodVisibility: `private_class_method` requires a singleton method definition (9:24-9:39)",
|
|
2344
|
+
],
|
|
2345
|
+
severity: Severity::Warning
|
|
2316
2346
|
);
|
|
2317
2347
|
}
|
|
2318
2348
|
|
|
@@ -2346,7 +2376,7 @@ mod visibility_tests {
|
|
|
2346
2376
|
|
|
2347
2377
|
assert_local_diagnostics_eq!(
|
|
2348
2378
|
&context,
|
|
2349
|
-
vec!["
|
|
2379
|
+
vec!["InvalidMethodVisibility: `private_class_method` called with a non-literal argument (5:28-5:40)"]
|
|
2350
2380
|
);
|
|
2351
2381
|
|
|
2352
2382
|
assert_definition_at!(&context, "5:25-5:26", MethodVisibility, |def| {
|
|
@@ -2367,7 +2397,7 @@ mod visibility_tests {
|
|
|
2367
2397
|
|
|
2368
2398
|
assert_local_diagnostics_eq!(
|
|
2369
2399
|
&context,
|
|
2370
|
-
vec!["
|
|
2400
|
+
vec!["InvalidMethodVisibility: `private_class_method` called at top level (1:1-1:32)"]
|
|
2371
2401
|
);
|
|
2372
2402
|
assert_constant_references_eq!(&context, ["NESTED_REF"]);
|
|
2373
2403
|
}
|
|
@@ -2452,7 +2482,7 @@ mod visibility_tests {
|
|
|
2452
2482
|
assert_local_diagnostics_eq!(
|
|
2453
2483
|
&context,
|
|
2454
2484
|
vec![
|
|
2455
|
-
"
|
|
2485
|
+
"InvalidMethodVisibility: `private_class_method` array element must be a Symbol, String, or method definition (5:32-5:42)"
|
|
2456
2486
|
]
|
|
2457
2487
|
);
|
|
2458
2488
|
|
|
@@ -2480,9 +2510,7 @@ mod visibility_tests {
|
|
|
2480
2510
|
|
|
2481
2511
|
assert_local_diagnostics_eq!(
|
|
2482
2512
|
&context,
|
|
2483
|
-
vec![
|
|
2484
|
-
"invalid-method-visibility: `private_class_method` requires a singleton method definition (2:25-2:49)"
|
|
2485
|
-
]
|
|
2513
|
+
vec!["InvalidMethodVisibility: `private_class_method` requires a singleton method definition (2:25-2:49)"]
|
|
2486
2514
|
);
|
|
2487
2515
|
|
|
2488
2516
|
for def in context.graph().definitions().values() {
|
|
@@ -2514,7 +2542,7 @@ mod visibility_tests {
|
|
|
2514
2542
|
assert_local_diagnostics_eq!(
|
|
2515
2543
|
&context,
|
|
2516
2544
|
vec![
|
|
2517
|
-
"
|
|
2545
|
+
"InvalidMethodVisibility: `private_class_method` array argument must be the only argument (5:24-5:28)"
|
|
2518
2546
|
]
|
|
2519
2547
|
);
|
|
2520
2548
|
|
|
@@ -2817,8 +2845,8 @@ mod constant_reference_tests {
|
|
|
2817
2845
|
assert_local_diagnostics_eq!(
|
|
2818
2846
|
&context,
|
|
2819
2847
|
[
|
|
2820
|
-
"
|
|
2821
|
-
"
|
|
2848
|
+
"DynamicConstantReference: Dynamic constant reference (3:6-3:14)",
|
|
2849
|
+
"ParseWarning: assigned but unused variable - foo (5:1-5:4)",
|
|
2822
2850
|
]
|
|
2823
2851
|
);
|
|
2824
2852
|
|
|
@@ -3001,7 +3029,7 @@ mod method_reference_tests {
|
|
|
3001
3029
|
|
|
3002
3030
|
assert_local_diagnostics_eq!(
|
|
3003
3031
|
&context,
|
|
3004
|
-
["
|
|
3032
|
+
["ParseError: unexpected ... when the parent method is not forwarding (31:5-31:8)"]
|
|
3005
3033
|
);
|
|
3006
3034
|
|
|
3007
3035
|
assert_method_references_eq!(
|
|
@@ -3087,18 +3115,18 @@ mod method_reference_tests {
|
|
|
3087
3115
|
assert_local_diagnostics_eq!(
|
|
3088
3116
|
&context,
|
|
3089
3117
|
[
|
|
3090
|
-
"
|
|
3091
|
-
"
|
|
3092
|
-
"
|
|
3093
|
-
"
|
|
3094
|
-
"
|
|
3095
|
-
"
|
|
3096
|
-
"
|
|
3097
|
-
"
|
|
3098
|
-
"
|
|
3099
|
-
"
|
|
3100
|
-
"
|
|
3101
|
-
"
|
|
3118
|
+
"ParseWarning: possibly useless use of != in void context (1:1-1:7)",
|
|
3119
|
+
"ParseWarning: possibly useless use of % in void context (2:1-2:6)",
|
|
3120
|
+
"ParseWarning: possibly useless use of & in void context (3:1-3:6)",
|
|
3121
|
+
"ParseWarning: possibly useless use of * in void context (5:1-5:6)",
|
|
3122
|
+
"ParseWarning: possibly useless use of ** in void context (6:1-6:7)",
|
|
3123
|
+
"ParseWarning: possibly useless use of + in void context (7:1-7:6)",
|
|
3124
|
+
"ParseWarning: possibly useless use of - in void context (8:1-8:6)",
|
|
3125
|
+
"ParseWarning: possibly useless use of / in void context (9:1-9:6)",
|
|
3126
|
+
"ParseWarning: possibly useless use of == in void context (11:1-11:7)",
|
|
3127
|
+
"ParseWarning: possibly useless use of ^ in void context (14:1-14:6)",
|
|
3128
|
+
"ParseWarning: possibly useless use of | in void context (15:1-15:6)",
|
|
3129
|
+
"ParseWarning: possibly useless use of <=> in void context (17:1-17:8)"
|
|
3102
3130
|
]
|
|
3103
3131
|
);
|
|
3104
3132
|
|
|
@@ -3120,7 +3148,7 @@ mod method_reference_tests {
|
|
|
3120
3148
|
|
|
3121
3149
|
assert_local_diagnostics_eq!(
|
|
3122
3150
|
&context,
|
|
3123
|
-
["
|
|
3151
|
+
["ParseWarning: possibly useless use of < in void context (1:1-1:6)"]
|
|
3124
3152
|
);
|
|
3125
3153
|
|
|
3126
3154
|
assert_method_references_eq!(&context, ["x", "<", "<=>", "y"]);
|
|
@@ -3136,7 +3164,7 @@ mod method_reference_tests {
|
|
|
3136
3164
|
|
|
3137
3165
|
assert_local_diagnostics_eq!(
|
|
3138
3166
|
&context,
|
|
3139
|
-
["
|
|
3167
|
+
["ParseWarning: possibly useless use of <= in void context (1:1-1:7)"]
|
|
3140
3168
|
);
|
|
3141
3169
|
|
|
3142
3170
|
assert_method_references_eq!(&context, ["x", "<=", "<=>", "y"]);
|
|
@@ -3152,7 +3180,7 @@ mod method_reference_tests {
|
|
|
3152
3180
|
|
|
3153
3181
|
assert_local_diagnostics_eq!(
|
|
3154
3182
|
&context,
|
|
3155
|
-
["
|
|
3183
|
+
["ParseWarning: possibly useless use of > in void context (1:1-1:6)"]
|
|
3156
3184
|
);
|
|
3157
3185
|
|
|
3158
3186
|
assert_method_references_eq!(&context, ["x", "<=>", ">", "y"]);
|
|
@@ -3168,7 +3196,7 @@ mod method_reference_tests {
|
|
|
3168
3196
|
|
|
3169
3197
|
assert_local_diagnostics_eq!(
|
|
3170
3198
|
&context,
|
|
3171
|
-
["
|
|
3199
|
+
["ParseWarning: possibly useless use of >= in void context (1:1-1:7)"]
|
|
3172
3200
|
);
|
|
3173
3201
|
|
|
3174
3202
|
assert_method_references_eq!(&context, ["x", "<=>", ">=", "y"]);
|
|
@@ -3672,10 +3700,10 @@ mod superclass_tests {
|
|
|
3672
3700
|
assert_local_diagnostics_eq!(
|
|
3673
3701
|
&context,
|
|
3674
3702
|
[
|
|
3675
|
-
"
|
|
3676
|
-
"
|
|
3677
|
-
"
|
|
3678
|
-
"
|
|
3703
|
+
"DynamicAncestor: Dynamic superclass (1:13-1:24)",
|
|
3704
|
+
"DynamicAncestor: Dynamic superclass (2:13-2:16)",
|
|
3705
|
+
"DynamicConstantReference: Dynamic constant reference (4:13-4:16)",
|
|
3706
|
+
"DynamicAncestor: Dynamic superclass (4:13-4:21)",
|
|
3679
3707
|
]
|
|
3680
3708
|
);
|
|
3681
3709
|
|
|
@@ -3858,15 +3886,15 @@ mod mixin_tests {
|
|
|
3858
3886
|
assert_local_diagnostics_eq!(
|
|
3859
3887
|
&context,
|
|
3860
3888
|
[
|
|
3861
|
-
"
|
|
3862
|
-
"
|
|
3863
|
-
"
|
|
3864
|
-
"
|
|
3865
|
-
"
|
|
3866
|
-
"
|
|
3867
|
-
"
|
|
3868
|
-
"
|
|
3869
|
-
"
|
|
3889
|
+
"DynamicConstantReference: Dynamic constant reference (1:9-1:12)",
|
|
3890
|
+
"DynamicAncestor: Dynamic mixin argument (1:9-1:17)",
|
|
3891
|
+
"DynamicConstantReference: Dynamic constant reference (2:9-2:12)",
|
|
3892
|
+
"DynamicAncestor: Dynamic mixin argument (2:9-2:17)",
|
|
3893
|
+
"DynamicConstantReference: Dynamic constant reference (3:8-3:11)",
|
|
3894
|
+
"DynamicAncestor: Dynamic mixin argument (3:8-3:16)",
|
|
3895
|
+
"DynamicAncestor: Dynamic mixin argument (5:9-5:12)",
|
|
3896
|
+
"DynamicAncestor: Dynamic mixin argument (6:9-6:12)",
|
|
3897
|
+
"DynamicAncestor: Dynamic mixin argument (7:8-7:11)"
|
|
3870
3898
|
]
|
|
3871
3899
|
);
|
|
3872
3900
|
assert!(context.graph().definitions().is_empty());
|
|
@@ -3885,9 +3913,9 @@ mod mixin_tests {
|
|
|
3885
3913
|
assert_local_diagnostics_eq!(
|
|
3886
3914
|
&context,
|
|
3887
3915
|
[
|
|
3888
|
-
"
|
|
3889
|
-
"
|
|
3890
|
-
"
|
|
3916
|
+
"TopLevelMixinSelf: Top level mixin self (1:9-1:13)",
|
|
3917
|
+
"TopLevelMixinSelf: Top level mixin self (2:9-2:13)",
|
|
3918
|
+
"TopLevelMixinSelf: Top level mixin self (3:8-3:12)"
|
|
3891
3919
|
]
|
|
3892
3920
|
);
|
|
3893
3921
|
|
|
@@ -5168,6 +5196,29 @@ mod dynamic_namespace_tests {
|
|
|
5168
5196
|
});
|
|
5169
5197
|
}
|
|
5170
5198
|
|
|
5199
|
+
#[test]
|
|
5200
|
+
fn index_extend_self_in_anonymous_module() {
|
|
5201
|
+
let context = index_source({
|
|
5202
|
+
"
|
|
5203
|
+
Module.new do
|
|
5204
|
+
extend self
|
|
5205
|
+
end
|
|
5206
|
+
"
|
|
5207
|
+
});
|
|
5208
|
+
assert_no_local_diagnostics!(&context);
|
|
5209
|
+
|
|
5210
|
+
assert_definition_at!(&context, "1:1-3:4", Module, |anonymous_module| {
|
|
5211
|
+
let extend = anonymous_module.mixins().first().unwrap();
|
|
5212
|
+
let constant_reference = context
|
|
5213
|
+
.graph()
|
|
5214
|
+
.constant_references()
|
|
5215
|
+
.get(extend.constant_reference_id())
|
|
5216
|
+
.unwrap();
|
|
5217
|
+
|
|
5218
|
+
assert_eq!(anonymous_module.name_id(), constant_reference.name_id());
|
|
5219
|
+
});
|
|
5220
|
+
}
|
|
5221
|
+
|
|
5171
5222
|
#[test]
|
|
5172
5223
|
fn index_singleton_method_in_class_new() {
|
|
5173
5224
|
let context = index_source({
|
|
@@ -5261,9 +5312,10 @@ mod diagnostic_tests {
|
|
|
5261
5312
|
assert_local_diagnostics_eq!(
|
|
5262
5313
|
&context,
|
|
5263
5314
|
[
|
|
5264
|
-
"
|
|
5265
|
-
"
|
|
5266
|
-
]
|
|
5315
|
+
"ParseError: expected an `end` to close the `class` statement (1:1-1:6)",
|
|
5316
|
+
"ParseError: unexpected end-of-input, assuming it is closing the parent top level context (1:10-2:1)"
|
|
5317
|
+
],
|
|
5318
|
+
severity: Severity::Error
|
|
5267
5319
|
);
|
|
5268
5320
|
|
|
5269
5321
|
// We still index the definition, even though it has errors
|
|
@@ -5283,7 +5335,8 @@ mod diagnostic_tests {
|
|
|
5283
5335
|
|
|
5284
5336
|
assert_local_diagnostics_eq!(
|
|
5285
5337
|
&context,
|
|
5286
|
-
["
|
|
5338
|
+
["ParseWarning: assigned but unused variable - foo (1:1-1:4)"],
|
|
5339
|
+
severity: Severity::Warning
|
|
5287
5340
|
);
|
|
5288
5341
|
}
|
|
5289
5342
|
}
|
data/rust/rubydex/src/lib.rs
CHANGED
data/rust/rubydex/src/listing.rs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
errors::Errors,
|
|
3
3
|
job_queue::{Job, JobQueue},
|
|
4
|
+
path_helpers,
|
|
4
5
|
};
|
|
5
6
|
use crossbeam_channel::{Sender, unbounded};
|
|
6
7
|
use glob::Pattern;
|
|
@@ -129,7 +130,7 @@ pub fn collect_file_paths<S: BuildHasher>(
|
|
|
129
130
|
Arc::new(excluded.iter().filter_map(|entry| Pattern::new(entry).ok()).collect());
|
|
130
131
|
|
|
131
132
|
for path in paths {
|
|
132
|
-
let Ok(path) = std::path::absolute(&path) else {
|
|
133
|
+
let Ok(path) = std::path::absolute(&path).map(path_helpers::simplified) else {
|
|
133
134
|
errors_tx
|
|
134
135
|
.send(Errors::FileError(format!("Failed to resolve path `{path}`")))
|
|
135
136
|
.expect("errors receiver dropped before run completion");
|
|
@@ -420,6 +421,30 @@ mod tests {
|
|
|
420
421
|
assert_eq!(files, [foo.to_str().unwrap().to_string()]);
|
|
421
422
|
}
|
|
422
423
|
|
|
424
|
+
#[cfg(windows)]
|
|
425
|
+
#[test]
|
|
426
|
+
fn collect_files_excludes_a_directory_below_a_verbatim_root() {
|
|
427
|
+
// Exclusions are joined onto the workspace path the configuration resolved, which is spelled plainly. A root
|
|
428
|
+
// given verbatim only matches them once it is spelled that way too.
|
|
429
|
+
let context = Context::new();
|
|
430
|
+
context.touch(&PathBuf::from("excluded").join("skipped.rb"));
|
|
431
|
+
|
|
432
|
+
let mut excluded = HashSet::new();
|
|
433
|
+
excluded.insert(
|
|
434
|
+
context
|
|
435
|
+
.absolute_path_to("excluded")
|
|
436
|
+
.to_string_lossy()
|
|
437
|
+
.replace('\\', "/")
|
|
438
|
+
.into_boxed_str(),
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
let (files, errors) =
|
|
442
|
+
collect_file_paths(vec![format!(r"\\?\{}", context.absolute_path().display())], &excluded);
|
|
443
|
+
|
|
444
|
+
assert!(errors.is_empty());
|
|
445
|
+
assert!(files.is_empty(), "expected the exclusion to apply: {files:?}");
|
|
446
|
+
}
|
|
447
|
+
|
|
423
448
|
#[test]
|
|
424
449
|
fn collect_files_excludes_nested_files_matching_globs() {
|
|
425
450
|
let context = Context::new();
|
data/rust/rubydex/src/main.rs
CHANGED
|
@@ -2,6 +2,7 @@ use clap::{Parser, ValueEnum};
|
|
|
2
2
|
use std::{fs, mem, path::PathBuf};
|
|
3
3
|
|
|
4
4
|
use rubydex::{
|
|
5
|
+
config::Config,
|
|
5
6
|
dot,
|
|
6
7
|
indexing::{self, IndexerBackend},
|
|
7
8
|
integrity, listing,
|
|
@@ -104,10 +105,12 @@ fn main() {
|
|
|
104
105
|
let mut graph = Graph::new();
|
|
105
106
|
|
|
106
107
|
if let Some(workspace_path) = workspace_path_for(&args.paths) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
match Config::load(&workspace_path) {
|
|
109
|
+
Ok(config) => graph.load_config(&config),
|
|
110
|
+
Err(error) => {
|
|
111
|
+
eprintln!("{error}");
|
|
112
|
+
std::process::exit(1);
|
|
113
|
+
}
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
|