@@ -993,6 +993,21 @@ impl<'a> Resolver<'a> {
993993 Outcome :: Resolved ( owner_id, id_needing_linearization) => {
994994 let mut fully_qualified_name = self . graph . strings ( ) . get ( & str_id) . unwrap ( ) . to_string ( ) ;
995995
996+ // If the owner is a promotable constant and something is being defined inside it, promote it to a
997+ // module
998+ {
999+ let owner = self . graph . declarations ( ) . get ( & owner_id) . unwrap ( ) ;
1000+ let is_promotable_constant =
1001+ matches ! ( owner, Declaration :: Constant ( _) ) && self . graph . all_definitions_promotable ( owner) ;
1002+
1003+ if is_promotable_constant {
1004+ self . graph . promote_constant_to_namespace ( owner_id, |name, owner_id| {
1005+ Declaration :: Namespace ( Namespace :: Module ( Box :: new ( ModuleDeclaration :: new ( name, owner_id) ) ) )
1006+ } ) ;
1007+ self . unit_queue . push_back ( Unit :: Ancestors ( owner_id) ) ;
1008+ }
1009+ }
1010+
9961011 let owner = self . graph . declarations ( ) . get ( & owner_id) . unwrap ( ) ;
9971012 let owner_is_namespace = owner. as_namespace ( ) . is_some ( ) ;
9981013
@@ -5185,4 +5200,21 @@ mod tests {
51855200 assert_declaration_exists ! ( context, "Foo::<Foo>#class_method()" ) ;
51865201 assert_declaration_exists ! ( context, "Foo#initialize()" ) ;
51875202 }
5203+
5204+ #[ test]
5205+ fn defining_constant_in_promotable_constant ( ) {
5206+ let mut context = GraphTest :: new ( ) ;
5207+ context. index_uri ( "file:///a.rb" , {
5208+ r"
5209+ Foo = dynamic
5210+ Foo::Bar = dynamic
5211+ Foo::Bar::Baz = 123
5212+ "
5213+ } ) ;
5214+
5215+ context. resolve ( ) ;
5216+ assert_declaration_kind_eq ! ( context, "Foo" , "Module" ) ;
5217+ assert_declaration_kind_eq ! ( context, "Foo::Bar" , "Module" ) ;
5218+ assert_declaration_kind_eq ! ( context, "Foo::Bar::Baz" , "Constant" ) ;
5219+ }
51885220}
0 commit comments