Skip to content

Commit 6792ca9

Browse files
authored
Merge pull request #785 from Shopify/04-18-ensure_descendants_are_cleaned_up_when_removing_a_top_level_declaration
Ensure descendants are cleaned up when removing a top level declaration
2 parents 99b0a04 + dfa4e03 commit 6792ca9

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

rust/rubydex/src/model/graph.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,10 @@ impl Graph {
12731273
let unqualified_str_id = StringId::from(&decl.unqualified_name());
12741274
let owner_id = *decl.owner_id();
12751275
let is_singleton_class = matches!(decl, Declaration::Namespace(Namespace::SingletonClass(_)));
1276+
let ancestors_to_detach: Vec<Ancestor> = decl
1277+
.as_namespace()
1278+
.map(|ns| ns.ancestors().iter().copied().collect())
1279+
.unwrap_or_default();
12761280

12771281
for def_id in def_ids {
12781282
self.push_work(Unit::Definition(def_id));
@@ -1287,6 +1291,16 @@ impl Graph {
12871291
ns.remove_member(&unqualified_str_id);
12881292
}
12891293
}
1294+
1295+
// Detach from each complete ancestor's descendant set so we don't leave a stale id in descendants
1296+
for ancestor in ancestors_to_detach {
1297+
if let Ancestor::Complete(ancestor_id) = ancestor
1298+
&& let Some(anc_decl) = self.declarations.get_mut(&ancestor_id)
1299+
&& let Some(ns) = anc_decl.as_namespace_mut()
1300+
{
1301+
ns.remove_descendant(&decl_id);
1302+
}
1303+
}
12901304
}
12911305

12921306
self.declarations.remove(&decl_id);
@@ -2534,6 +2548,7 @@ mod tests {
25342548

25352549
#[cfg(test)]
25362550
mod incremental_resolution_tests {
2551+
use crate::model::ids::DeclarationId;
25372552
use crate::model::name::NameRef;
25382553
use crate::test_utils::GraphTest;
25392554
use crate::{
@@ -4161,4 +4176,37 @@ mod incremental_resolution_tests {
41614176
assert_declaration_exists!(context, "Foo::<Foo>");
41624177
assert_declaration_exists!(context, "Bar::<Bar>");
41634178
}
4179+
4180+
#[test]
4181+
fn constant_references_through_object_inheritance_are_invalidated() {
4182+
let mut context = GraphTest::new();
4183+
context.index_uri("file:///a.rb", "class Foo; end");
4184+
context.index_uri(
4185+
"file:///b.rb",
4186+
r"
4187+
module Wrap
4188+
class Foo; end
4189+
::Foo
4190+
Foo
4191+
end
4192+
",
4193+
);
4194+
context.resolve();
4195+
4196+
context.delete_uri("file:///a.rb");
4197+
context.resolve();
4198+
4199+
let kernel = context
4200+
.graph()
4201+
.declarations()
4202+
.get(&DeclarationId::from("Kernel"))
4203+
.unwrap();
4204+
4205+
for id in kernel.as_namespace().unwrap().descendants() {
4206+
assert!(
4207+
context.graph().declarations().contains_key(id),
4208+
"Kernel has stale descendant id {id:?} with no backing declaration"
4209+
);
4210+
}
4211+
}
41644212
} // mod incremental_resolution_tests

0 commit comments

Comments
 (0)