rubydex 0.2.0 → 0.2.2
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/ext/rubydex/declaration.c +38 -0
- data/ext/rubydex/definition.c +27 -0
- data/ext/rubydex/graph.c +70 -17
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/signature.c +83 -0
- data/ext/rubydex/signature.h +23 -0
- data/lib/rubydex/declaration.rb +31 -0
- data/lib/rubydex/signature.rb +130 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +1 -0
- data/rbi/rubydex.rbi +41 -11
- data/rust/rubydex/src/diagnostic.rs +1 -0
- data/rust/rubydex/src/indexing/ruby_indexer.rs +75 -15
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +2832 -2663
- data/rust/rubydex/src/model/declaration.rs +48 -0
- data/rust/rubydex/src/model/definitions.rs +41 -9
- data/rust/rubydex/src/model/graph.rs +276 -46
- data/rust/rubydex/src/query.rs +2073 -160
- data/rust/rubydex/src/resolution.rs +202 -71
- data/rust/rubydex/src/resolution_tests.rs +333 -1
- data/rust/rubydex-sys/src/declaration_api.rs +29 -33
- data/rust/rubydex-sys/src/graph_api.rs +89 -5
- data/rust/rubydex-sys/src/lib.rs +1 -0
- data/rust/rubydex-sys/src/signature_api.rs +209 -0
- metadata +6 -2
|
@@ -339,6 +339,54 @@ impl Declaration {
|
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
#[must_use]
|
|
343
|
+
pub fn as_constant(&self) -> Option<&ConstantDeclaration> {
|
|
344
|
+
match self {
|
|
345
|
+
Declaration::Constant(constant) => Some(constant),
|
|
346
|
+
_ => None,
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
#[must_use]
|
|
351
|
+
pub fn as_constant_alias(&self) -> Option<&ConstantAliasDeclaration> {
|
|
352
|
+
match self {
|
|
353
|
+
Declaration::ConstantAlias(alias) => Some(alias),
|
|
354
|
+
_ => None,
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
#[must_use]
|
|
359
|
+
pub fn as_method(&self) -> Option<&MethodDeclaration> {
|
|
360
|
+
match self {
|
|
361
|
+
Declaration::Method(method) => Some(method),
|
|
362
|
+
_ => None,
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
#[must_use]
|
|
367
|
+
pub fn as_global_variable(&self) -> Option<&GlobalVariableDeclaration> {
|
|
368
|
+
match self {
|
|
369
|
+
Declaration::GlobalVariable(global) => Some(global),
|
|
370
|
+
_ => None,
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
#[must_use]
|
|
375
|
+
pub fn as_class_variable(&self) -> Option<&ClassVariableDeclaration> {
|
|
376
|
+
match self {
|
|
377
|
+
Declaration::ClassVariable(cvar) => Some(cvar),
|
|
378
|
+
_ => None,
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
#[must_use]
|
|
383
|
+
pub fn as_instance_variable(&self) -> Option<&InstanceVariableDeclaration> {
|
|
384
|
+
match self {
|
|
385
|
+
Declaration::InstanceVariable(ivar) => Some(ivar),
|
|
386
|
+
_ => None,
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
342
390
|
#[must_use]
|
|
343
391
|
pub fn definitions(&self) -> &[DefinitionId] {
|
|
344
392
|
all_declarations!(self, it => &it.definition_ids)
|
|
@@ -40,6 +40,7 @@ bitflags! {
|
|
|
40
40
|
pub struct DefinitionFlags: u8 {
|
|
41
41
|
const DEPRECATED = 0b0001;
|
|
42
42
|
const PROMOTABLE = 0b0010;
|
|
43
|
+
const SINGLETON_METHOD_VISIBILITY = 0b0100;
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -53,6 +54,11 @@ impl DefinitionFlags {
|
|
|
53
54
|
pub fn is_promotable(&self) -> bool {
|
|
54
55
|
self.contains(Self::PROMOTABLE)
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
#[must_use]
|
|
59
|
+
pub fn is_singleton_method_visibility(&self) -> bool {
|
|
60
|
+
self.contains(Self::SINGLETON_METHOD_VISIBILITY)
|
|
61
|
+
}
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
#[derive(Debug)]
|
|
@@ -155,8 +161,8 @@ impl Definition {
|
|
|
155
161
|
Definition::Module(d) => Some(d.name_id()),
|
|
156
162
|
Definition::Constant(d) => Some(d.name_id()),
|
|
157
163
|
Definition::ConstantAlias(d) => Some(d.name_id()),
|
|
158
|
-
Definition::ConstantVisibility(
|
|
159
|
-
Definition::MethodVisibility(_)
|
|
164
|
+
Definition::ConstantVisibility(_)
|
|
165
|
+
| Definition::MethodVisibility(_)
|
|
160
166
|
| Definition::GlobalVariable(_)
|
|
161
167
|
| Definition::InstanceVariable(_)
|
|
162
168
|
| Definition::ClassVariable(_)
|
|
@@ -711,7 +717,8 @@ impl ConstantAliasDefinition {
|
|
|
711
717
|
|
|
712
718
|
#[derive(Debug)]
|
|
713
719
|
pub struct ConstantVisibilityDefinition {
|
|
714
|
-
|
|
720
|
+
receiver: Option<NameId>,
|
|
721
|
+
target: StringId,
|
|
715
722
|
visibility: Visibility,
|
|
716
723
|
uri_id: UriId,
|
|
717
724
|
offset: Offset,
|
|
@@ -722,8 +729,10 @@ pub struct ConstantVisibilityDefinition {
|
|
|
722
729
|
|
|
723
730
|
impl ConstantVisibilityDefinition {
|
|
724
731
|
#[must_use]
|
|
732
|
+
#[allow(clippy::too_many_arguments)]
|
|
725
733
|
pub const fn new(
|
|
726
|
-
|
|
734
|
+
receiver: Option<NameId>,
|
|
735
|
+
target: StringId,
|
|
727
736
|
visibility: Visibility,
|
|
728
737
|
uri_id: UriId,
|
|
729
738
|
offset: Offset,
|
|
@@ -732,7 +741,8 @@ impl ConstantVisibilityDefinition {
|
|
|
732
741
|
lexical_nesting_id: Option<DefinitionId>,
|
|
733
742
|
) -> Self {
|
|
734
743
|
Self {
|
|
735
|
-
|
|
744
|
+
receiver,
|
|
745
|
+
target,
|
|
736
746
|
visibility,
|
|
737
747
|
uri_id,
|
|
738
748
|
offset,
|
|
@@ -744,12 +754,17 @@ impl ConstantVisibilityDefinition {
|
|
|
744
754
|
|
|
745
755
|
#[must_use]
|
|
746
756
|
pub fn id(&self) -> DefinitionId {
|
|
747
|
-
DefinitionId::from(&format!("{}{}{}", *self.uri_id, self.offset.start(), *self.
|
|
757
|
+
DefinitionId::from(&format!("{}{}{}", *self.uri_id, self.offset.start(), *self.target))
|
|
748
758
|
}
|
|
749
759
|
|
|
750
760
|
#[must_use]
|
|
751
|
-
pub fn
|
|
752
|
-
&self.
|
|
761
|
+
pub fn receiver(&self) -> &Option<NameId> {
|
|
762
|
+
&self.receiver
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
#[must_use]
|
|
766
|
+
pub fn target(&self) -> &StringId {
|
|
767
|
+
&self.target
|
|
753
768
|
}
|
|
754
769
|
|
|
755
770
|
#[must_use]
|
|
@@ -782,7 +797,7 @@ impl ConstantVisibilityDefinition {
|
|
|
782
797
|
&self.flags
|
|
783
798
|
}
|
|
784
799
|
}
|
|
785
|
-
assert_mem_size!(ConstantVisibilityDefinition,
|
|
800
|
+
assert_mem_size!(ConstantVisibilityDefinition, 64);
|
|
786
801
|
|
|
787
802
|
#[derive(Debug)]
|
|
788
803
|
pub struct MethodVisibilityDefinition {
|
|
@@ -1024,6 +1039,23 @@ pub enum Parameter {
|
|
|
1024
1039
|
}
|
|
1025
1040
|
assert_mem_size!(Parameter, 24);
|
|
1026
1041
|
|
|
1042
|
+
impl Parameter {
|
|
1043
|
+
#[must_use]
|
|
1044
|
+
pub fn inner(&self) -> &ParameterStruct {
|
|
1045
|
+
match self {
|
|
1046
|
+
Parameter::RequiredPositional(s)
|
|
1047
|
+
| Parameter::OptionalPositional(s)
|
|
1048
|
+
| Parameter::RestPositional(s)
|
|
1049
|
+
| Parameter::Post(s)
|
|
1050
|
+
| Parameter::RequiredKeyword(s)
|
|
1051
|
+
| Parameter::OptionalKeyword(s)
|
|
1052
|
+
| Parameter::RestKeyword(s)
|
|
1053
|
+
| Parameter::Forward(s)
|
|
1054
|
+
| Parameter::Block(s) => s,
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1027
1059
|
#[derive(Debug, Clone)]
|
|
1028
1060
|
pub struct ParameterStruct {
|
|
1029
1061
|
offset: Offset,
|
|
@@ -6,7 +6,7 @@ use crate::diagnostic::Diagnostic;
|
|
|
6
6
|
use crate::indexing::local_graph::LocalGraph;
|
|
7
7
|
use crate::model::built_in::{OBJECT_ID, add_built_in_data};
|
|
8
8
|
use crate::model::declaration::{Ancestor, Declaration, Namespace};
|
|
9
|
-
use crate::model::definitions::{Definition, Receiver};
|
|
9
|
+
use crate::model::definitions::{Definition, MethodVisibilityDefinition, Receiver};
|
|
10
10
|
use crate::model::document::Document;
|
|
11
11
|
use crate::model::encoding::Encoding;
|
|
12
12
|
use crate::model::identity_maps::{IdentityHashMap, IdentityHashSet};
|
|
@@ -260,10 +260,7 @@ impl Graph {
|
|
|
260
260
|
let name = self.names.get(it.name_id()).unwrap();
|
|
261
261
|
name.str()
|
|
262
262
|
}
|
|
263
|
-
Definition::ConstantVisibility(it) =>
|
|
264
|
-
let name = self.names.get(it.name_id()).unwrap();
|
|
265
|
-
name.str()
|
|
266
|
-
}
|
|
263
|
+
Definition::ConstantVisibility(it) => it.target(),
|
|
267
264
|
Definition::MethodVisibility(it) => it.str_id(),
|
|
268
265
|
Definition::GlobalVariable(it) => it.str_id(),
|
|
269
266
|
Definition::InstanceVariable(it) => it.str_id(),
|
|
@@ -291,6 +288,16 @@ impl Graph {
|
|
|
291
288
|
&self.documents
|
|
292
289
|
}
|
|
293
290
|
|
|
291
|
+
/// Attaches a diagnostic to the document with the given `uri_id`. The diagnostic clears
|
|
292
|
+
/// automatically when the document is deleted or re-indexed.
|
|
293
|
+
///
|
|
294
|
+
/// # Panics
|
|
295
|
+
///
|
|
296
|
+
/// Panics if no document is registered for `uri_id`.
|
|
297
|
+
pub fn add_document_diagnostic(&mut self, uri_id: UriId, diagnostic: Diagnostic) {
|
|
298
|
+
self.documents.get_mut(&uri_id).unwrap().add_diagnostic(diagnostic);
|
|
299
|
+
}
|
|
300
|
+
|
|
294
301
|
/// # Panics
|
|
295
302
|
///
|
|
296
303
|
/// Panics if the definition is not found
|
|
@@ -320,13 +327,21 @@ impl Graph {
|
|
|
320
327
|
Definition::ConstantAlias(it) => {
|
|
321
328
|
return self.name_id_to_declaration_id(*it.name_id());
|
|
322
329
|
}
|
|
323
|
-
Definition::ConstantVisibility(it) =>
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
it.str_id(),
|
|
330
|
+
Definition::ConstantVisibility(it) => (
|
|
331
|
+
it.receiver()
|
|
332
|
+
.as_ref()
|
|
333
|
+
.or_else(|| self.find_enclosing_namespace_name_id(it.lexical_nesting_id().as_ref())),
|
|
334
|
+
it.target(),
|
|
329
335
|
),
|
|
336
|
+
Definition::MethodVisibility(it) => {
|
|
337
|
+
if it.flags().is_singleton_method_visibility() {
|
|
338
|
+
return self.find_singleton_method_visibility_declaration(it);
|
|
339
|
+
}
|
|
340
|
+
(
|
|
341
|
+
self.find_enclosing_namespace_name_id(it.lexical_nesting_id().as_ref()),
|
|
342
|
+
it.str_id(),
|
|
343
|
+
)
|
|
344
|
+
}
|
|
330
345
|
Definition::GlobalVariable(it) => (
|
|
331
346
|
self.find_enclosing_namespace_name_id(it.lexical_nesting_id().as_ref()),
|
|
332
347
|
it.str_id(),
|
|
@@ -365,13 +380,15 @@ impl Graph {
|
|
|
365
380
|
)
|
|
366
381
|
}
|
|
367
382
|
Definition::MethodAlias(it) => {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
it.
|
|
374
|
-
|
|
383
|
+
let nesting_name_id = match it.receiver() {
|
|
384
|
+
Some(Receiver::SelfReceiver(def_id)) => {
|
|
385
|
+
return self.find_self_receiver_declaration(*def_id, *it.new_name_str_id());
|
|
386
|
+
}
|
|
387
|
+
Some(Receiver::ConstantReceiver(name_id)) => Some(name_id),
|
|
388
|
+
None => self.find_enclosing_namespace_name_id(it.lexical_nesting_id().as_ref()),
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
(nesting_name_id, it.new_name_str_id())
|
|
375
392
|
}
|
|
376
393
|
};
|
|
377
394
|
|
|
@@ -403,6 +420,27 @@ impl Graph {
|
|
|
403
420
|
None
|
|
404
421
|
}
|
|
405
422
|
|
|
423
|
+
/// Looks up the declaration for a singleton method visibility through the singleton class.
|
|
424
|
+
fn find_singleton_method_visibility_declaration(
|
|
425
|
+
&self,
|
|
426
|
+
definition: &MethodVisibilityDefinition,
|
|
427
|
+
) -> Option<&DeclarationId> {
|
|
428
|
+
let nesting_name_id = self.find_enclosing_namespace_name_id(definition.lexical_nesting_id().as_ref());
|
|
429
|
+
let nesting_declaration_id = match nesting_name_id {
|
|
430
|
+
Some(name_id) => self.name_id_to_declaration_id(*name_id),
|
|
431
|
+
None => Some(&*OBJECT_ID),
|
|
432
|
+
}?;
|
|
433
|
+
let singleton_id = self
|
|
434
|
+
.declarations
|
|
435
|
+
.get(nesting_declaration_id)?
|
|
436
|
+
.as_namespace()?
|
|
437
|
+
.singleton_class()?;
|
|
438
|
+
self.declarations
|
|
439
|
+
.get(singleton_id)?
|
|
440
|
+
.as_namespace()?
|
|
441
|
+
.member(definition.str_id())
|
|
442
|
+
}
|
|
443
|
+
|
|
406
444
|
/// Looks up the declaration for a `SelfReceiver` method/alias through the singleton class.
|
|
407
445
|
fn find_self_receiver_declaration(&self, def_id: DefinitionId, member_str_id: StringId) -> Option<&DeclarationId> {
|
|
408
446
|
let owner_decl_id = self.definition_id_to_declaration_id(def_id)?;
|
|
@@ -602,42 +640,50 @@ impl Graph {
|
|
|
602
640
|
&self.name_dependents
|
|
603
641
|
}
|
|
604
642
|
|
|
605
|
-
/// Returns the visibility for a
|
|
643
|
+
/// Returns the visibility for a declaration.
|
|
606
644
|
///
|
|
607
|
-
///
|
|
608
|
-
///
|
|
609
|
-
/// - Otherwise, falls back to the latest method-like definition's indexed visibility
|
|
610
|
-
/// - Returns `None` if the declaration has no definitions with visibility
|
|
645
|
+
/// For methods, the latest definition wins. For constants, the latest
|
|
646
|
+
/// `private_constant`/`public_constant` wins, otherwise `Public`.
|
|
611
647
|
#[must_use]
|
|
612
648
|
pub fn visibility(&self, declaration_id: &DeclarationId) -> Option<Visibility> {
|
|
613
649
|
let declaration = self.declarations.get(declaration_id)?;
|
|
614
650
|
let definitions = declaration.definitions();
|
|
615
651
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
Definition::
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
Definition::AttrWriter(attr) => return Some(*attr.visibility()),
|
|
625
|
-
Definition::Class(_)
|
|
626
|
-
| Definition::SingletonClass(_)
|
|
627
|
-
| Definition::Module(_)
|
|
628
|
-
| Definition::Constant(_)
|
|
629
|
-
| Definition::ConstantAlias(_)
|
|
630
|
-
| Definition::ConstantVisibility(_)
|
|
631
|
-
| Definition::GlobalVariable(_)
|
|
632
|
-
| Definition::InstanceVariable(_)
|
|
633
|
-
| Definition::ClassVariable(_)
|
|
634
|
-
| Definition::MethodAlias(_)
|
|
635
|
-
| Definition::GlobalVariableAlias(_) => {}
|
|
652
|
+
match declaration {
|
|
653
|
+
Declaration::Namespace(Namespace::Class(_) | Namespace::Module(_))
|
|
654
|
+
| Declaration::Constant(_)
|
|
655
|
+
| Declaration::ConstantAlias(_) => {
|
|
656
|
+
for def_id in definitions.iter().rev() {
|
|
657
|
+
if let Some(Definition::ConstantVisibility(vis)) = self.definitions.get(def_id) {
|
|
658
|
+
return Some(*vis.visibility());
|
|
659
|
+
}
|
|
636
660
|
}
|
|
661
|
+
Some(Visibility::Public)
|
|
662
|
+
}
|
|
663
|
+
Declaration::Method(_) => {
|
|
664
|
+
for def_id in definitions.iter().rev() {
|
|
665
|
+
let Some(definition) = self.definitions.get(def_id) else {
|
|
666
|
+
continue;
|
|
667
|
+
};
|
|
668
|
+
let visibility = match definition {
|
|
669
|
+
Definition::MethodVisibility(vis) => Some(*vis.visibility()),
|
|
670
|
+
Definition::Method(method) => Some(*method.visibility()),
|
|
671
|
+
Definition::AttrAccessor(attr) => Some(*attr.visibility()),
|
|
672
|
+
Definition::AttrReader(attr) => Some(*attr.visibility()),
|
|
673
|
+
Definition::AttrWriter(attr) => Some(*attr.visibility()),
|
|
674
|
+
_ => None,
|
|
675
|
+
};
|
|
676
|
+
if visibility.is_some() {
|
|
677
|
+
return visibility;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
None
|
|
637
681
|
}
|
|
682
|
+
Declaration::Namespace(Namespace::SingletonClass(_) | Namespace::Todo(_))
|
|
683
|
+
| Declaration::GlobalVariable(_)
|
|
684
|
+
| Declaration::InstanceVariable(_)
|
|
685
|
+
| Declaration::ClassVariable(_) => None,
|
|
638
686
|
}
|
|
639
|
-
|
|
640
|
-
None
|
|
641
687
|
}
|
|
642
688
|
|
|
643
689
|
/// Drains the accumulated work items, returning them for use by the resolver.
|
|
@@ -645,7 +691,7 @@ impl Graph {
|
|
|
645
691
|
std::mem::take(&mut self.pending_work)
|
|
646
692
|
}
|
|
647
693
|
|
|
648
|
-
fn push_work(&mut self, unit: Unit) {
|
|
694
|
+
pub(crate) fn push_work(&mut self, unit: Unit) {
|
|
649
695
|
self.pending_work.push(unit);
|
|
650
696
|
}
|
|
651
697
|
|
|
@@ -2398,6 +2444,34 @@ mod incremental_resolution_tests {
|
|
|
2398
2444
|
}
|
|
2399
2445
|
}
|
|
2400
2446
|
|
|
2447
|
+
/// Compares incremental resolution against a fresh index at the declaration-ID level.
|
|
2448
|
+
///
|
|
2449
|
+
/// This is a broad consistency check: it catches both stale declarations left
|
|
2450
|
+
/// behind by incremental invalidation and declarations that incremental
|
|
2451
|
+
/// resolution failed to recreate.
|
|
2452
|
+
fn assert_declaration_ids_match(incremental: &GraphTest, fresh: &GraphTest) {
|
|
2453
|
+
let extras: Vec<_> = incremental
|
|
2454
|
+
.graph()
|
|
2455
|
+
.declarations()
|
|
2456
|
+
.iter()
|
|
2457
|
+
.filter(|(id, _)| !fresh.graph().declarations().contains_key(id))
|
|
2458
|
+
.map(|(_, d)| format!("{} ({})", d.name(), d.kind()))
|
|
2459
|
+
.collect();
|
|
2460
|
+
|
|
2461
|
+
let missing: Vec<_> = fresh
|
|
2462
|
+
.graph()
|
|
2463
|
+
.declarations()
|
|
2464
|
+
.iter()
|
|
2465
|
+
.filter(|(id, _)| !incremental.graph().declarations().contains_key(id))
|
|
2466
|
+
.map(|(_, d)| format!("{} ({})", d.name(), d.kind()))
|
|
2467
|
+
.collect();
|
|
2468
|
+
|
|
2469
|
+
assert!(
|
|
2470
|
+
extras.is_empty() && missing.is_empty(),
|
|
2471
|
+
"Declaration mismatch:\n Extra: {extras:?}\n Missing: {missing:?}"
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2401
2475
|
#[test]
|
|
2402
2476
|
fn new_namespace_shadowing_include_target_invalidates_references() {
|
|
2403
2477
|
let mut context = GraphTest::new();
|
|
@@ -3772,6 +3846,162 @@ mod incremental_resolution_tests {
|
|
|
3772
3846
|
assert_declaration_exists!(context, "Parent::Target::<Target>");
|
|
3773
3847
|
}
|
|
3774
3848
|
|
|
3849
|
+
#[test]
|
|
3850
|
+
fn singleton_definition_survives_receiver_delete_readd() {
|
|
3851
|
+
let mut incremental = GraphTest::new();
|
|
3852
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3853
|
+
incremental.index_uri("file:///singleton.rb", "class << Foo; def bar; end; end");
|
|
3854
|
+
incremental.resolve();
|
|
3855
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>");
|
|
3856
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3857
|
+
|
|
3858
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3859
|
+
incremental.resolve();
|
|
3860
|
+
assert_declaration_does_not_exist!(incremental, "Foo");
|
|
3861
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>");
|
|
3862
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#bar()");
|
|
3863
|
+
assert_declaration_does_not_exist!(incremental, "Object#bar()");
|
|
3864
|
+
|
|
3865
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3866
|
+
incremental.resolve();
|
|
3867
|
+
|
|
3868
|
+
let mut fresh = GraphTest::new();
|
|
3869
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3870
|
+
fresh.index_uri("file:///singleton.rb", "class << Foo; def bar; end; end");
|
|
3871
|
+
fresh.resolve();
|
|
3872
|
+
|
|
3873
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
3874
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
#[test]
|
|
3878
|
+
fn explicit_singleton_method_survives_receiver_delete_readd() {
|
|
3879
|
+
let mut incremental = GraphTest::new();
|
|
3880
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3881
|
+
incremental.index_uri("file:///singleton.rb", "def Foo.bar; end");
|
|
3882
|
+
incremental.resolve();
|
|
3883
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3884
|
+
|
|
3885
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3886
|
+
incremental.resolve();
|
|
3887
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#bar()");
|
|
3888
|
+
|
|
3889
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3890
|
+
incremental.resolve();
|
|
3891
|
+
|
|
3892
|
+
let mut fresh = GraphTest::new();
|
|
3893
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3894
|
+
fresh.index_uri("file:///singleton.rb", "def Foo.bar; end");
|
|
3895
|
+
fresh.resolve();
|
|
3896
|
+
|
|
3897
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
3898
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3899
|
+
}
|
|
3900
|
+
|
|
3901
|
+
#[test]
|
|
3902
|
+
fn explicit_singleton_method_ivar_survives_receiver_delete_readd() {
|
|
3903
|
+
let mut incremental = GraphTest::new();
|
|
3904
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3905
|
+
incremental.index_uri("file:///singleton.rb", "def Foo.bar; @x = 1; end");
|
|
3906
|
+
incremental.resolve();
|
|
3907
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3908
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#@x");
|
|
3909
|
+
|
|
3910
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3911
|
+
incremental.resolve();
|
|
3912
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#bar()");
|
|
3913
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#@x");
|
|
3914
|
+
|
|
3915
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3916
|
+
incremental.resolve();
|
|
3917
|
+
|
|
3918
|
+
let mut fresh = GraphTest::new();
|
|
3919
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3920
|
+
fresh.index_uri("file:///singleton.rb", "def Foo.bar; @x = 1; end");
|
|
3921
|
+
fresh.resolve();
|
|
3922
|
+
|
|
3923
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
3924
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#bar()");
|
|
3925
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#@x");
|
|
3926
|
+
}
|
|
3927
|
+
|
|
3928
|
+
#[test]
|
|
3929
|
+
fn constant_receiver_method_alias_survives_receiver_delete_readd() {
|
|
3930
|
+
let mut incremental = GraphTest::new();
|
|
3931
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3932
|
+
incremental.index_uri("file:///alias.rb", "Foo.alias_method :new_name, :old_name");
|
|
3933
|
+
incremental.resolve();
|
|
3934
|
+
assert_declaration_exists!(incremental, "Foo#new_name()");
|
|
3935
|
+
|
|
3936
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3937
|
+
incremental.resolve();
|
|
3938
|
+
assert_declaration_does_not_exist!(incremental, "Foo#new_name()");
|
|
3939
|
+
|
|
3940
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3941
|
+
incremental.resolve();
|
|
3942
|
+
|
|
3943
|
+
let mut fresh = GraphTest::new();
|
|
3944
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3945
|
+
fresh.index_uri("file:///alias.rb", "Foo.alias_method :new_name, :old_name");
|
|
3946
|
+
fresh.resolve();
|
|
3947
|
+
|
|
3948
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
3949
|
+
assert_declaration_exists!(incremental, "Foo#new_name()");
|
|
3950
|
+
}
|
|
3951
|
+
|
|
3952
|
+
#[test]
|
|
3953
|
+
fn singleton_body_method_alias_survives_receiver_delete_readd() {
|
|
3954
|
+
let mut incremental = GraphTest::new();
|
|
3955
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3956
|
+
incremental.index_uri("file:///singleton.rb", "class << Foo; def old; end; alias new old; end");
|
|
3957
|
+
incremental.resolve();
|
|
3958
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#old()");
|
|
3959
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#new()");
|
|
3960
|
+
|
|
3961
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3962
|
+
incremental.resolve();
|
|
3963
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#old()");
|
|
3964
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>#new()");
|
|
3965
|
+
assert_declaration_does_not_exist!(incremental, "Object#old()");
|
|
3966
|
+
assert_declaration_does_not_exist!(incremental, "Object#new()");
|
|
3967
|
+
|
|
3968
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3969
|
+
incremental.resolve();
|
|
3970
|
+
|
|
3971
|
+
let mut fresh = GraphTest::new();
|
|
3972
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3973
|
+
fresh.index_uri("file:///singleton.rb", "class << Foo; def old; end; alias new old; end");
|
|
3974
|
+
fresh.resolve();
|
|
3975
|
+
|
|
3976
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
3977
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>#new()");
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
#[test]
|
|
3981
|
+
fn singleton_body_ivar_survives_receiver_delete_readd() {
|
|
3982
|
+
let mut incremental = GraphTest::new();
|
|
3983
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3984
|
+
incremental.index_uri("file:///singleton.rb", "class << Foo; @bar = 1; end");
|
|
3985
|
+
incremental.resolve();
|
|
3986
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>::<<Foo>>#@bar");
|
|
3987
|
+
|
|
3988
|
+
incremental.delete_uri("file:///foo.rb");
|
|
3989
|
+
incremental.resolve();
|
|
3990
|
+
assert_declaration_does_not_exist!(incremental, "Foo::<Foo>::<<Foo>>#@bar");
|
|
3991
|
+
assert_declaration_does_not_exist!(incremental, "Object::<Object>#@bar");
|
|
3992
|
+
|
|
3993
|
+
incremental.index_uri("file:///foo.rb", "class Foo; end");
|
|
3994
|
+
incremental.resolve();
|
|
3995
|
+
|
|
3996
|
+
let mut fresh = GraphTest::new();
|
|
3997
|
+
fresh.index_uri("file:///foo.rb", "class Foo; end");
|
|
3998
|
+
fresh.index_uri("file:///singleton.rb", "class << Foo; @bar = 1; end");
|
|
3999
|
+
fresh.resolve();
|
|
4000
|
+
|
|
4001
|
+
assert_declaration_ids_match(&incremental, &fresh);
|
|
4002
|
+
assert_declaration_exists!(incremental, "Foo::<Foo>::<<Foo>>#@bar");
|
|
4003
|
+
}
|
|
4004
|
+
|
|
3775
4005
|
#[test]
|
|
3776
4006
|
fn no_duplicate_definition_on_identical_file_delete_readd() {
|
|
3777
4007
|
let source = "class Foo; def self.run; end; def run; end; end";
|