@@ -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
@@ -5119,4 +5134,21 @@ mod tests {
51195134 assert_declaration_exists ! ( context, "Foo::<Foo>#class_method()" ) ;
51205135 assert_declaration_exists ! ( context, "Foo#initialize()" ) ;
51215136 }
5137+
5138+ #[ test]
5139+ fn defining_constant_in_promotable_constant ( ) {
5140+ let mut context = GraphTest :: new ( ) ;
5141+ context. index_uri ( "file:///a.rb" , {
5142+ r"
5143+ Foo = dynamic
5144+ Foo::Bar = dynamic
5145+ Foo::Bar::Baz = 123
5146+ "
5147+ } ) ;
5148+
5149+ context. resolve ( ) ;
5150+ assert_declaration_kind_eq ! ( context, "Foo" , "Module" ) ;
5151+ assert_declaration_kind_eq ! ( context, "Foo::Bar" , "Module" ) ;
5152+ assert_declaration_kind_eq ! ( context, "Foo::Bar::Baz" , "Constant" ) ;
5153+ }
51225154}
0 commit comments