rubydex 0.2.9 → 0.3.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 +69 -3
- data/THIRD_PARTY_LICENSES.html +34 -1
- data/exe/rdx +131 -55
- data/ext/rubydex/declaration.c +1 -1
- data/ext/rubydex/definition.c +32 -4
- data/ext/rubydex/graph.c +14 -3
- data/ext/rubydex/query.c +105 -0
- data/ext/rubydex/query.h +8 -0
- data/ext/rubydex/reference.c +60 -0
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/utils.c +12 -0
- data/ext/rubydex/utils.h +5 -0
- data/lib/rubydex/version.rb +1 -1
- data/rbi/rubydex.rbi +22 -0
- data/rust/Cargo.lock +7 -0
- data/rust/rubydex/Cargo.toml +1 -0
- data/rust/rubydex/benches/graph_memory.rs +22 -4
- data/rust/rubydex/src/compile_assertions.rs +15 -0
- data/rust/rubydex/src/diagnostic.rs +1 -1
- data/rust/rubydex/src/indexing/rbs_indexer.rs +14 -2
- data/rust/rubydex/src/indexing/ruby_indexer.rs +49 -58
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +72 -16
- data/rust/rubydex/src/main.rs +2 -124
- data/rust/rubydex/src/model/declaration.rs +0 -11
- data/rust/rubydex/src/model/definitions.rs +27 -26
- data/rust/rubydex/src/model/document.rs +43 -7
- data/rust/rubydex/src/model/graph.rs +40 -28
- data/rust/rubydex/src/model/id.rs +55 -0
- data/rust/rubydex/src/model/ids.rs +21 -9
- data/rust/rubydex/src/model/name.rs +35 -7
- data/rust/rubydex/src/model/references.rs +16 -13
- data/rust/rubydex/src/operation/ruby_builder.rs +48 -59
- data/rust/rubydex/src/query/cypher/schema.rs +790 -0
- data/rust/rubydex/src/query/cypher/schema_info.rs +161 -0
- data/rust/rubydex/src/query/cypher/tests.rs +228 -0
- data/rust/rubydex/src/query/cypher.rs +57 -0
- data/rust/rubydex/src/query.rs +2 -0
- data/rust/rubydex/src/resolution.rs +248 -227
- data/rust/rubydex/src/resolution_tests.rs +263 -65
- data/rust/rubydex-sys/src/declaration_api.rs +6 -3
- data/rust/rubydex-sys/src/definition_api.rs +27 -7
- data/rust/rubydex-sys/src/graph_api.rs +158 -14
- data/rust/rubydex-sys/src/reference_api.rs +58 -12
- metadata +8 -2
|
@@ -10,7 +10,6 @@ use crate::{
|
|
|
10
10
|
assert_no_diagnostics, assert_no_members, assert_owner_eq, assert_singleton_class_eq,
|
|
11
11
|
diagnostic::Rule,
|
|
12
12
|
model::{declaration::Ancestors, ids::DeclarationId, name::NameRef},
|
|
13
|
-
resolution::Resolver,
|
|
14
13
|
test_utils::GraphTest,
|
|
15
14
|
};
|
|
16
15
|
|
|
@@ -3097,13 +3096,14 @@ mod declaration_creation_tests {
|
|
|
3097
3096
|
#[test]
|
|
3098
3097
|
fn resolution_for_ambiguous_namespace_definitions() {
|
|
3099
3098
|
// Like many examples of Ruby code that is ambiguous to static analysis, this example is ambiguous due to
|
|
3100
|
-
// require order. If `
|
|
3101
|
-
// error or warning for a non existing constant.
|
|
3099
|
+
// require order. If `a_qualified.rb` is loaded first, then `Bar` doesn't exist, Ruby crashes and we should
|
|
3100
|
+
// emit an error or warning for a non existing constant.
|
|
3102
3101
|
//
|
|
3103
|
-
// If `
|
|
3104
|
-
// escaping the `Foo` nesting.
|
|
3102
|
+
// If `z_parent.rb` is loaded first, then `Bar` resolves to top level `Bar` and `Bar::Baz` is defined,
|
|
3103
|
+
// completely escaping the `Foo` nesting. The URIs intentionally sort in the opposite order: name complexity
|
|
3104
|
+
// must take precedence over URI so the top level `Bar` is resolved before the qualified `Bar::Baz` definition.
|
|
3105
3105
|
let mut context = graph_test();
|
|
3106
|
-
context.index_uri("file:///
|
|
3106
|
+
context.index_uri("file:///a_qualified.rb", {
|
|
3107
3107
|
r"
|
|
3108
3108
|
module Foo
|
|
3109
3109
|
class Bar::Baz
|
|
@@ -3111,7 +3111,7 @@ mod declaration_creation_tests {
|
|
|
3111
3111
|
end
|
|
3112
3112
|
"
|
|
3113
3113
|
});
|
|
3114
|
-
context.index_uri("file:///
|
|
3114
|
+
context.index_uri("file:///z_parent.rb", {
|
|
3115
3115
|
r"
|
|
3116
3116
|
module Bar
|
|
3117
3117
|
end
|
|
@@ -3123,62 +3123,11 @@ mod declaration_creation_tests {
|
|
|
3123
3123
|
|
|
3124
3124
|
assert_no_members!(context, "Foo");
|
|
3125
3125
|
assert_owner_eq!(context, "Foo", "Object");
|
|
3126
|
+
assert_declaration_does_not_exist!(context, "Foo::Bar");
|
|
3126
3127
|
|
|
3127
3128
|
assert_members_eq!(context, "Bar", ["Baz"]);
|
|
3128
3129
|
assert_owner_eq!(context, "Bar", "Object");
|
|
3129
3130
|
}
|
|
3130
|
-
|
|
3131
|
-
#[test]
|
|
3132
|
-
fn expected_name_depth_order() {
|
|
3133
|
-
let mut context = graph_test();
|
|
3134
|
-
context.index_uri("file:///foo.rb", {
|
|
3135
|
-
r"
|
|
3136
|
-
module Foo
|
|
3137
|
-
module Bar
|
|
3138
|
-
module Baz
|
|
3139
|
-
end
|
|
3140
|
-
|
|
3141
|
-
module ::Top
|
|
3142
|
-
class AfterTop
|
|
3143
|
-
end
|
|
3144
|
-
end
|
|
3145
|
-
end
|
|
3146
|
-
|
|
3147
|
-
module Qux::Zip
|
|
3148
|
-
module Zap
|
|
3149
|
-
class Zop::Boop
|
|
3150
|
-
end
|
|
3151
|
-
end
|
|
3152
|
-
end
|
|
3153
|
-
end
|
|
3154
|
-
"
|
|
3155
|
-
});
|
|
3156
|
-
|
|
3157
|
-
let depths = Resolver::compute_name_depths(context.graph().names());
|
|
3158
|
-
let mut names = context
|
|
3159
|
-
.graph()
|
|
3160
|
-
.names()
|
|
3161
|
-
.iter()
|
|
3162
|
-
.filter(|(_, n)| {
|
|
3163
|
-
!["Kernel", "BasicObject", "Object", "Module", "Class"]
|
|
3164
|
-
.contains(&context.graph().strings().get(n.str()).unwrap().as_str())
|
|
3165
|
-
})
|
|
3166
|
-
.collect::<Vec<_>>();
|
|
3167
|
-
assert_eq!(10, names.len());
|
|
3168
|
-
|
|
3169
|
-
names.sort_by_key(|(id, _)| depths.get(id).unwrap());
|
|
3170
|
-
|
|
3171
|
-
assert_eq!(
|
|
3172
|
-
[
|
|
3173
|
-
"Top", "Foo", "Bar", "Qux", "AfterTop", "Baz", "Zip", "Zap", "Zop", "Boop"
|
|
3174
|
-
],
|
|
3175
|
-
names
|
|
3176
|
-
.iter()
|
|
3177
|
-
.map(|(_, n)| context.graph().strings().get(n.str()).unwrap().as_str())
|
|
3178
|
-
.collect::<Vec<_>>()
|
|
3179
|
-
.as_slice()
|
|
3180
|
-
);
|
|
3181
|
-
}
|
|
3182
3131
|
}
|
|
3183
3132
|
|
|
3184
3133
|
mod singleton_class_tests {
|
|
@@ -4535,6 +4484,7 @@ mod promotability_tests {
|
|
|
4535
4484
|
|
|
4536
4485
|
context.resolve();
|
|
4537
4486
|
assert_no_diagnostics!(&context);
|
|
4487
|
+
assert_declaration_kind_eq!(context, "Qux", "<TODO>");
|
|
4538
4488
|
assert_declaration_exists!(context, "Qux::<Qux>");
|
|
4539
4489
|
}
|
|
4540
4490
|
|
|
@@ -4570,9 +4520,8 @@ mod promotability_tests {
|
|
|
4570
4520
|
|
|
4571
4521
|
#[test]
|
|
4572
4522
|
fn promoted_constant_has_correct_ancestors() {
|
|
4573
|
-
// When a promotable constant is auto-promoted via singleton class access,
|
|
4574
|
-
//
|
|
4575
|
-
// Modules don't inherit from Object.
|
|
4523
|
+
// When a promotable constant is auto-promoted via singleton class access, its kind remains unknown.
|
|
4524
|
+
// Todos do not inherit from Object.
|
|
4576
4525
|
let mut context = graph_test();
|
|
4577
4526
|
context.index_uri("file:///foo.rb", {
|
|
4578
4527
|
r"
|
|
@@ -4583,6 +4532,7 @@ mod promotability_tests {
|
|
|
4583
4532
|
|
|
4584
4533
|
context.resolve();
|
|
4585
4534
|
assert_no_diagnostics!(&context);
|
|
4535
|
+
assert_declaration_kind_eq!(context, "Foo", "<TODO>");
|
|
4586
4536
|
assert_ancestors_eq!(context, "Foo", ["Foo"]);
|
|
4587
4537
|
}
|
|
4588
4538
|
|
|
@@ -4633,8 +4583,8 @@ mod promotability_tests {
|
|
|
4633
4583
|
});
|
|
4634
4584
|
|
|
4635
4585
|
context.resolve();
|
|
4636
|
-
assert_declaration_kind_eq!(context, "Foo", "
|
|
4637
|
-
assert_declaration_kind_eq!(context, "Foo::Bar", "
|
|
4586
|
+
assert_declaration_kind_eq!(context, "Foo", "<TODO>");
|
|
4587
|
+
assert_declaration_kind_eq!(context, "Foo::Bar", "<TODO>");
|
|
4638
4588
|
assert_declaration_kind_eq!(context, "Foo::Bar::Baz", "Constant");
|
|
4639
4589
|
}
|
|
4640
4590
|
|
|
@@ -4652,7 +4602,7 @@ mod promotability_tests {
|
|
|
4652
4602
|
});
|
|
4653
4603
|
|
|
4654
4604
|
context.resolve();
|
|
4655
|
-
assert_declaration_kind_eq!(context, "Foo", "
|
|
4605
|
+
assert_declaration_kind_eq!(context, "Foo", "<TODO>");
|
|
4656
4606
|
assert_declaration_exists!(context, "Foo::<Foo>#bar()");
|
|
4657
4607
|
}
|
|
4658
4608
|
|
|
@@ -4675,6 +4625,33 @@ mod promotability_tests {
|
|
|
4675
4625
|
assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
|
|
4676
4626
|
}
|
|
4677
4627
|
|
|
4628
|
+
#[test]
|
|
4629
|
+
fn rbs_constant_is_promotable_for_singleton_call() {
|
|
4630
|
+
let mut context = graph_test();
|
|
4631
|
+
context.index_rbs_uri("file:///env.rbs", "ENV: untyped");
|
|
4632
|
+
context.index_uri("file:///env.rb", {
|
|
4633
|
+
r#"
|
|
4634
|
+
ENV.fetch("FEATURE")
|
|
4635
|
+
"#
|
|
4636
|
+
});
|
|
4637
|
+
context.resolve();
|
|
4638
|
+
|
|
4639
|
+
assert_no_diagnostics!(&context);
|
|
4640
|
+
assert_declaration_exists!(context, "ENV::<ENV>");
|
|
4641
|
+
|
|
4642
|
+
let fetch = context
|
|
4643
|
+
.graph()
|
|
4644
|
+
.method_references()
|
|
4645
|
+
.values()
|
|
4646
|
+
.find(|method| *method.str() == "fetch".into())
|
|
4647
|
+
.expect("ENV.fetch should be indexed");
|
|
4648
|
+
let receiver_name_id = fetch.receiver().expect("ENV.fetch should have a receiver");
|
|
4649
|
+
let NameRef::Resolved(receiver) = context.graph().names().get(&receiver_name_id).unwrap() else {
|
|
4650
|
+
panic!("ENV.fetch receiver should resolve");
|
|
4651
|
+
};
|
|
4652
|
+
assert_eq!(*receiver.declaration_id(), DeclarationId::from("ENV::<ENV>"));
|
|
4653
|
+
}
|
|
4654
|
+
|
|
4678
4655
|
#[test]
|
|
4679
4656
|
fn ivar_defined_inside_of_undefined_alias_namespace() {
|
|
4680
4657
|
let mut context = graph_test();
|
|
@@ -4882,6 +4859,67 @@ mod rbs_tests {
|
|
|
4882
4859
|
assert_declaration_exists!(context, "Foo::Bar::Baz");
|
|
4883
4860
|
}
|
|
4884
4861
|
|
|
4862
|
+
#[test]
|
|
4863
|
+
fn rbs_qualified_mixin_resolves_through_parent_scope() {
|
|
4864
|
+
let mut context = graph_test();
|
|
4865
|
+
context.index_rbs_uri("file:///minitest.rbs", {
|
|
4866
|
+
r"
|
|
4867
|
+
module Minitest
|
|
4868
|
+
module Guard
|
|
4869
|
+
end
|
|
4870
|
+
|
|
4871
|
+
module Assertions
|
|
4872
|
+
end
|
|
4873
|
+
|
|
4874
|
+
class Runnable
|
|
4875
|
+
end
|
|
4876
|
+
end
|
|
4877
|
+
"
|
|
4878
|
+
});
|
|
4879
|
+
context.index_rbs_uri("file:///minitest/test.rbs", {
|
|
4880
|
+
r"
|
|
4881
|
+
class Minitest::Test < ::Minitest::Runnable
|
|
4882
|
+
include Minitest::Assertions
|
|
4883
|
+
include Minitest::Guard
|
|
4884
|
+
extend Minitest::Guard
|
|
4885
|
+
end
|
|
4886
|
+
"
|
|
4887
|
+
});
|
|
4888
|
+
context.resolve();
|
|
4889
|
+
|
|
4890
|
+
assert_no_diagnostics!(&context);
|
|
4891
|
+
|
|
4892
|
+
assert_ancestors_eq!(
|
|
4893
|
+
context,
|
|
4894
|
+
"Minitest::Test",
|
|
4895
|
+
[
|
|
4896
|
+
"Minitest::Test",
|
|
4897
|
+
"Minitest::Guard",
|
|
4898
|
+
"Minitest::Assertions",
|
|
4899
|
+
"Minitest::Runnable",
|
|
4900
|
+
"Object",
|
|
4901
|
+
"Kernel",
|
|
4902
|
+
"BasicObject"
|
|
4903
|
+
]
|
|
4904
|
+
);
|
|
4905
|
+
assert_ancestors_eq!(
|
|
4906
|
+
context,
|
|
4907
|
+
"Minitest::Test::<Test>",
|
|
4908
|
+
[
|
|
4909
|
+
"Minitest::Test::<Test>",
|
|
4910
|
+
"Minitest::Guard",
|
|
4911
|
+
"Minitest::Runnable::<Runnable>",
|
|
4912
|
+
"Object::<Object>",
|
|
4913
|
+
"BasicObject::<BasicObject>",
|
|
4914
|
+
"Class",
|
|
4915
|
+
"Module",
|
|
4916
|
+
"Object",
|
|
4917
|
+
"Kernel",
|
|
4918
|
+
"BasicObject"
|
|
4919
|
+
]
|
|
4920
|
+
);
|
|
4921
|
+
}
|
|
4922
|
+
|
|
4885
4923
|
#[test]
|
|
4886
4924
|
fn rbs_qualified_name_inside_nested_module() {
|
|
4887
4925
|
let mut context = graph_test();
|
|
@@ -5641,4 +5679,164 @@ mod visibility_resolution_tests {
|
|
|
5641
5679
|
assert_visibility_eq!(context, "Foo::<Foo>#b()", Visibility::Private);
|
|
5642
5680
|
assert_visibility_eq!(context, "Foo::<Foo>#c()", Visibility::Public);
|
|
5643
5681
|
}
|
|
5682
|
+
|
|
5683
|
+
#[test]
|
|
5684
|
+
fn inline_module_function() {
|
|
5685
|
+
let mut context = GraphTest::new();
|
|
5686
|
+
context.index_uri(
|
|
5687
|
+
"file:///foo.rb",
|
|
5688
|
+
r"
|
|
5689
|
+
module Foo
|
|
5690
|
+
module_function def bar; end
|
|
5691
|
+
end
|
|
5692
|
+
",
|
|
5693
|
+
);
|
|
5694
|
+
context.resolve();
|
|
5695
|
+
|
|
5696
|
+
assert_no_diagnostics!(&context);
|
|
5697
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
|
|
5698
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
|
|
5699
|
+
}
|
|
5700
|
+
|
|
5701
|
+
#[test]
|
|
5702
|
+
fn inline_module_function_singleton_companion_visibility_can_be_changed() {
|
|
5703
|
+
let mut context = graph_test();
|
|
5704
|
+
context.index_uri(
|
|
5705
|
+
"file:///foo.rb",
|
|
5706
|
+
r"
|
|
5707
|
+
module Foo
|
|
5708
|
+
module_function def bar; end
|
|
5709
|
+
|
|
5710
|
+
class << self
|
|
5711
|
+
private :bar
|
|
5712
|
+
end
|
|
5713
|
+
end
|
|
5714
|
+
",
|
|
5715
|
+
);
|
|
5716
|
+
context.resolve();
|
|
5717
|
+
|
|
5718
|
+
assert_no_diagnostics!(&context);
|
|
5719
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
|
|
5720
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Private);
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
#[test]
|
|
5724
|
+
fn retroactive_module_function() {
|
|
5725
|
+
let mut context = GraphTest::new();
|
|
5726
|
+
context.index_uri(
|
|
5727
|
+
"file:///foo.rb",
|
|
5728
|
+
r"
|
|
5729
|
+
module Foo
|
|
5730
|
+
def bar; end
|
|
5731
|
+
module_function :bar
|
|
5732
|
+
end
|
|
5733
|
+
",
|
|
5734
|
+
);
|
|
5735
|
+
context.resolve();
|
|
5736
|
+
|
|
5737
|
+
assert_no_diagnostics!(&context);
|
|
5738
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Private);
|
|
5739
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
|
|
5740
|
+
|
|
5741
|
+
// Instance: Method def + MethodVisibility def
|
|
5742
|
+
assert_declaration_definitions_count_eq!(context, "Foo#bar()", 2);
|
|
5743
|
+
// Singleton companion: only the MethodVisibility def is attached
|
|
5744
|
+
assert_declaration_definitions_count_eq!(context, "Foo::<Foo>#bar()", 1);
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5747
|
+
#[test]
|
|
5748
|
+
fn retroactive_module_function_undefined_target_emits_single_diagnostic() {
|
|
5749
|
+
let mut context = GraphTest::new();
|
|
5750
|
+
context.index_uri(
|
|
5751
|
+
"file:///foo.rb",
|
|
5752
|
+
r"
|
|
5753
|
+
module Foo
|
|
5754
|
+
module_function :missing
|
|
5755
|
+
end
|
|
5756
|
+
",
|
|
5757
|
+
);
|
|
5758
|
+
context.resolve();
|
|
5759
|
+
|
|
5760
|
+
// The singleton-side def stays silent; only the instance-side def emits.
|
|
5761
|
+
assert_diagnostics_eq!(
|
|
5762
|
+
context,
|
|
5763
|
+
&["undefined-method-visibility-target: undefined method `Foo#missing()` for visibility change (2:20-2:27)"]
|
|
5764
|
+
);
|
|
5765
|
+
assert_declaration_does_not_exist!(context, "Foo::<Foo>#missing()");
|
|
5766
|
+
assert_declaration_does_not_exist!(context, "Foo::<Foo>");
|
|
5767
|
+
}
|
|
5768
|
+
|
|
5769
|
+
#[test]
|
|
5770
|
+
fn retroactive_module_function_singleton_companion_cleared_when_removed_multi_file() {
|
|
5771
|
+
let mut context = GraphTest::new();
|
|
5772
|
+
context.index_uri(
|
|
5773
|
+
"file:///a.rb",
|
|
5774
|
+
r"
|
|
5775
|
+
module Foo
|
|
5776
|
+
def bar; end
|
|
5777
|
+
module_function :bar
|
|
5778
|
+
end
|
|
5779
|
+
",
|
|
5780
|
+
);
|
|
5781
|
+
context.index_uri(
|
|
5782
|
+
"file:///b.rb",
|
|
5783
|
+
r"
|
|
5784
|
+
module Foo
|
|
5785
|
+
def baz; end
|
|
5786
|
+
end
|
|
5787
|
+
",
|
|
5788
|
+
);
|
|
5789
|
+
context.resolve();
|
|
5790
|
+
|
|
5791
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
|
|
5792
|
+
|
|
5793
|
+
// Re-index a.rb without `module_function :bar`. Foo still has b.rb's Module def, so the
|
|
5794
|
+
// namespace stays alive and no cascade through Foo's singleton class runs. The singleton
|
|
5795
|
+
// companion must still be cleaned up via reverse-lookup invalidation of its own def.
|
|
5796
|
+
context.index_uri(
|
|
5797
|
+
"file:///a.rb",
|
|
5798
|
+
r"
|
|
5799
|
+
module Foo
|
|
5800
|
+
def bar; end
|
|
5801
|
+
end
|
|
5802
|
+
",
|
|
5803
|
+
);
|
|
5804
|
+
context.resolve();
|
|
5805
|
+
|
|
5806
|
+
assert_no_diagnostics!(&context);
|
|
5807
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Public);
|
|
5808
|
+
assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
|
|
5809
|
+
}
|
|
5810
|
+
|
|
5811
|
+
#[test]
|
|
5812
|
+
fn retroactive_module_function_singleton_companion_cleared_when_removed() {
|
|
5813
|
+
let mut context = GraphTest::new();
|
|
5814
|
+
context.index_uri(
|
|
5815
|
+
"file:///foo.rb",
|
|
5816
|
+
r"
|
|
5817
|
+
module Foo
|
|
5818
|
+
def bar; end
|
|
5819
|
+
module_function :bar
|
|
5820
|
+
end
|
|
5821
|
+
",
|
|
5822
|
+
);
|
|
5823
|
+
context.resolve();
|
|
5824
|
+
|
|
5825
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Public);
|
|
5826
|
+
|
|
5827
|
+
context.index_uri(
|
|
5828
|
+
"file:///foo.rb",
|
|
5829
|
+
r"
|
|
5830
|
+
module Foo
|
|
5831
|
+
def bar; end
|
|
5832
|
+
end
|
|
5833
|
+
",
|
|
5834
|
+
);
|
|
5835
|
+
context.resolve();
|
|
5836
|
+
|
|
5837
|
+
assert_no_diagnostics!(&context);
|
|
5838
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Public);
|
|
5839
|
+
assert_declaration_does_not_exist!(context, "Foo::<Foo>#bar()");
|
|
5840
|
+
assert_declaration_does_not_exist!(context, "Foo::<Foo>");
|
|
5841
|
+
}
|
|
5644
5842
|
}
|
|
@@ -291,7 +291,8 @@ pub unsafe extern "C" fn rdx_declaration_singleton_class(pointer: GraphPointer,
|
|
|
291
291
|
})
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
/// Returns the owner of the declaration (attached object in the case of singleton classes)
|
|
294
|
+
/// Returns the owner of the declaration (attached object in the case of singleton classes), or NULL if the declaration
|
|
295
|
+
/// cannot be found.
|
|
295
296
|
///
|
|
296
297
|
/// # Safety
|
|
297
298
|
///
|
|
@@ -299,11 +300,13 @@ pub unsafe extern "C" fn rdx_declaration_singleton_class(pointer: GraphPointer,
|
|
|
299
300
|
///
|
|
300
301
|
/// # Panics
|
|
301
302
|
///
|
|
302
|
-
///
|
|
303
|
+
/// This function will panic if the owner declaration cannot be found.
|
|
303
304
|
#[unsafe(no_mangle)]
|
|
304
305
|
pub unsafe extern "C" fn rdx_declaration_owner(pointer: GraphPointer, decl_id: u64) -> *const CDeclaration {
|
|
305
306
|
with_graph(pointer, |graph| {
|
|
306
|
-
let declaration = graph.declarations().get(&DeclarationId::new(decl_id))
|
|
307
|
+
let Some(declaration) = graph.declarations().get(&DeclarationId::new(decl_id)) else {
|
|
308
|
+
return ptr::null();
|
|
309
|
+
};
|
|
307
310
|
let owner_id = *declaration.owner_id();
|
|
308
311
|
Box::into_raw(Box::new(CDeclaration::from_declaration(
|
|
309
312
|
owner_id,
|
|
@@ -156,21 +156,22 @@ pub struct CommentArray {
|
|
|
156
156
|
pub len: usize,
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
/// Returns a newly allocated array of comments (string and location) for the given definition id
|
|
160
|
-
/// Caller must free the returned pointer
|
|
159
|
+
/// Returns a newly allocated array of comments (string and location) for the given definition id, or NULL if the
|
|
160
|
+
/// definition cannot be found. Caller must free the returned pointer and its contents with
|
|
161
|
+
/// `rdx_definition_comments_free`.
|
|
161
162
|
///
|
|
162
163
|
/// # Safety
|
|
163
164
|
/// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
|
|
164
165
|
/// - `definition_id` must be a valid definition id.
|
|
165
166
|
///
|
|
166
167
|
/// # Panics
|
|
167
|
-
/// This function will panic if
|
|
168
|
+
/// This function will panic if the definition's document cannot be found.
|
|
168
169
|
#[unsafe(no_mangle)]
|
|
169
170
|
pub unsafe extern "C" fn rdx_definition_comments(pointer: GraphPointer, definition_id: u64) -> *mut CommentArray {
|
|
170
171
|
with_graph(pointer, |graph| {
|
|
171
172
|
let def_id = DefinitionId::new(definition_id);
|
|
172
173
|
let Some(defn) = graph.definitions().get(&def_id) else {
|
|
173
|
-
|
|
174
|
+
return ptr::null_mut();
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
let uri_id = *defn.uri_id();
|
|
@@ -229,7 +230,7 @@ pub unsafe extern "C" fn rdx_definition_comments_free(ptr: *mut CommentArray) {
|
|
|
229
230
|
// arr is dropped here
|
|
230
231
|
}
|
|
231
232
|
|
|
232
|
-
/// Returns a newly allocated `Location` for the given definition id.
|
|
233
|
+
/// Returns a newly allocated `Location` for the given definition id, or NULL if the definition cannot be found.
|
|
233
234
|
/// Caller must free the returned pointer with `rdx_location_free`.
|
|
234
235
|
///
|
|
235
236
|
/// # Safety
|
|
@@ -238,13 +239,13 @@ pub unsafe extern "C" fn rdx_definition_comments_free(ptr: *mut CommentArray) {
|
|
|
238
239
|
///
|
|
239
240
|
/// # Panics
|
|
240
241
|
///
|
|
241
|
-
/// This function will panic if
|
|
242
|
+
/// This function will panic if the definition's document cannot be found.
|
|
242
243
|
#[unsafe(no_mangle)]
|
|
243
244
|
pub unsafe extern "C" fn rdx_definition_location(pointer: GraphPointer, definition_id: u64) -> *mut Location {
|
|
244
245
|
with_graph(pointer, |graph| {
|
|
245
246
|
let def_id = DefinitionId::new(definition_id);
|
|
246
247
|
let Some(defn) = graph.definitions().get(&def_id) else {
|
|
247
|
-
|
|
248
|
+
return ptr::null_mut();
|
|
248
249
|
};
|
|
249
250
|
|
|
250
251
|
let document = graph.documents().get(defn.uri_id()).expect("document should exist");
|
|
@@ -493,6 +494,25 @@ pub unsafe extern "C" fn rdx_definition_mixins(pointer: GraphPointer, definition
|
|
|
493
494
|
})
|
|
494
495
|
}
|
|
495
496
|
|
|
497
|
+
/// Returns a pointer to the URI ID of the document a definition belongs to, or
|
|
498
|
+
/// NULL if the definition cannot be found. Caller must free the returned pointer
|
|
499
|
+
/// with `free_u64`.
|
|
500
|
+
///
|
|
501
|
+
/// # Safety
|
|
502
|
+
/// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
|
|
503
|
+
/// - `definition_id` must be a valid definition id.
|
|
504
|
+
#[unsafe(no_mangle)]
|
|
505
|
+
pub unsafe extern "C" fn rdx_definition_document(pointer: GraphPointer, definition_id: u64) -> *const u64 {
|
|
506
|
+
with_graph(pointer, |graph| {
|
|
507
|
+
let def_id = DefinitionId::new(definition_id);
|
|
508
|
+
if let Some(defn) = graph.definitions().get(&def_id) {
|
|
509
|
+
Box::into_raw(Box::new(**defn.uri_id())).cast_const()
|
|
510
|
+
} else {
|
|
511
|
+
ptr::null()
|
|
512
|
+
}
|
|
513
|
+
})
|
|
514
|
+
}
|
|
515
|
+
|
|
496
516
|
/// Status of a `MethodAliasDefinition#target` resolution.
|
|
497
517
|
#[repr(u8)]
|
|
498
518
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|