@@ -531,10 +531,9 @@ pub fn dealias_method(graph: &Graph, alias: &MethodAliasDefinition) -> Vec<Deali
531531 } ,
532532 } ;
533533
534- let owner_decl = graph. declarations ( ) . get ( & owner_id) . unwrap ( ) ;
535- let ns = owner_decl. as_namespace ( ) . unwrap ( ) ;
534+ let method_decl_id = find_member_in_ancestors ( graph, owner_id, * alias. old_name_str_id ( ) ) ;
536535
537- let Some ( & method_decl_id) = ns . member ( alias . old_name_str_id ( ) ) else {
536+ let Some ( method_decl_id) = method_decl_id else {
538537 return vec ! [ ] ;
539538 } ;
540539 let method_decl = graph. declarations ( ) . get ( & method_decl_id) . unwrap ( ) ;
@@ -551,6 +550,31 @@ pub fn dealias_method(graph: &Graph, alias: &MethodAliasDefinition) -> Vec<Deali
551550 . collect ( )
552551}
553552
553+ /// Searches for a member by `StringId` in the given namespace and its ancestor chain.
554+ #[ must_use]
555+ pub fn find_member_in_ancestors (
556+ graph : & Graph ,
557+ namespace_id : DeclarationId ,
558+ str_id : StringId ,
559+ ) -> Option < DeclarationId > {
560+ let ns = graph. declarations ( ) . get ( & namespace_id) ?. as_namespace ( ) ?;
561+
562+ if let Some ( & decl_id) = ns. member ( & str_id) {
563+ return Some ( decl_id) ;
564+ }
565+
566+ for ancestor in ns. ancestors ( ) {
567+ if let Ancestor :: Complete ( ancestor_id) = ancestor {
568+ let ancestor_ns = graph. declarations ( ) . get ( ancestor_id) ?. as_namespace ( ) ?;
569+ if let Some ( & decl_id) = ancestor_ns. member ( & str_id) {
570+ return Some ( decl_id) ;
571+ }
572+ }
573+ }
574+
575+ None
576+ }
577+
554578#[ cfg( test) ]
555579mod tests {
556580 use std:: str:: FromStr ;
@@ -1893,6 +1917,122 @@ mod tests {
18931917 ) ;
18941918 }
18951919
1920+ #[ test]
1921+ fn dealias_method_inherited ( ) {
1922+ let mut context = GraphTest :: new ( ) ;
1923+ context. index_uri ( "file:///foo.rb" , "
1924+ class Parent
1925+ def foo(a); end
1926+ end
1927+ class Child < Parent
1928+ alias bar foo
1929+ end
1930+ " ) ;
1931+ context. resolve ( ) ;
1932+
1933+ let alias = get_method_alias_def ( context. graph ( ) , "Child#bar()" ) ;
1934+ let results = dealias_method ( context. graph ( ) , alias) ;
1935+ assert_eq ! ( results. len( ) , 1 ) ;
1936+ assert ! ( matches!( results[ 0 ] , DealiasMethodResult :: Method ( _) ) ) ;
1937+ }
1938+
1939+ #[ test]
1940+ fn find_member_in_ancestors_direct ( ) {
1941+ let mut context = GraphTest :: new ( ) ;
1942+ context. index_uri ( "file:///foo.rb" , "
1943+ class Foo
1944+ def bar; end
1945+ end
1946+ " ) ;
1947+ context. resolve ( ) ;
1948+
1949+ let result = find_member_in_ancestors (
1950+ context. graph ( ) ,
1951+ DeclarationId :: from ( "Foo" ) ,
1952+ StringId :: from ( "bar()" ) ,
1953+ ) ;
1954+ assert_eq ! ( result, Some ( DeclarationId :: from( "Foo#bar()" ) ) ) ;
1955+ }
1956+
1957+ #[ test]
1958+ fn find_member_in_ancestors_inherited ( ) {
1959+ let mut context = GraphTest :: new ( ) ;
1960+ context. index_uri ( "file:///foo.rb" , "
1961+ class Parent
1962+ def foo; end
1963+ end
1964+ class Child < Parent
1965+ end
1966+ " ) ;
1967+ context. resolve ( ) ;
1968+
1969+ let result = find_member_in_ancestors (
1970+ context. graph ( ) ,
1971+ DeclarationId :: from ( "Child" ) ,
1972+ StringId :: from ( "foo()" ) ,
1973+ ) ;
1974+ assert_eq ! ( result, Some ( DeclarationId :: from( "Parent#foo()" ) ) ) ;
1975+ }
1976+
1977+ #[ test]
1978+ fn find_member_in_ancestors_overridden ( ) {
1979+ let mut context = GraphTest :: new ( ) ;
1980+ context. index_uri ( "file:///foo.rb" , "
1981+ class Parent
1982+ def foo; end
1983+ end
1984+ class Child < Parent
1985+ def foo; end
1986+ end
1987+ " ) ;
1988+ context. resolve ( ) ;
1989+
1990+ let result = find_member_in_ancestors (
1991+ context. graph ( ) ,
1992+ DeclarationId :: from ( "Child" ) ,
1993+ StringId :: from ( "foo()" ) ,
1994+ ) ;
1995+ assert_eq ! ( result, Some ( DeclarationId :: from( "Child#foo()" ) ) ) ;
1996+ }
1997+
1998+ #[ test]
1999+ fn find_member_in_ancestors_not_found ( ) {
2000+ let mut context = GraphTest :: new ( ) ;
2001+ context. index_uri ( "file:///foo.rb" , "
2002+ class Foo
2003+ end
2004+ " ) ;
2005+ context. resolve ( ) ;
2006+
2007+ let result = find_member_in_ancestors (
2008+ context. graph ( ) ,
2009+ DeclarationId :: from ( "Foo" ) ,
2010+ StringId :: from ( "nonexistent()" ) ,
2011+ ) ;
2012+ assert_eq ! ( result, None ) ;
2013+ }
2014+
2015+ #[ test]
2016+ fn find_member_in_ancestors_via_module ( ) {
2017+ let mut context = GraphTest :: new ( ) ;
2018+ context. index_uri ( "file:///foo.rb" , "
2019+ module Greetable
2020+ def greet; end
2021+ end
2022+ class Foo
2023+ include Greetable
2024+ end
2025+ " ) ;
2026+ context. resolve ( ) ;
2027+
2028+ let result = find_member_in_ancestors (
2029+ context. graph ( ) ,
2030+ DeclarationId :: from ( "Foo" ) ,
2031+ StringId :: from ( "greet()" ) ,
2032+ ) ;
2033+ assert_eq ! ( result, Some ( DeclarationId :: from( "Greetable#greet()" ) ) ) ;
2034+ }
2035+
18962036 #[ test]
18972037 fn method_call_completion_excludes_keywords ( ) {
18982038 let mut context = GraphTest :: new ( ) ;
0 commit comments