@@ -1306,15 +1306,40 @@ impl Jvm {
13061306 . and_then ( |super_class| self . get_class ( & super_class) ) ;
13071307 }
13081308
1309+ let mut visited = HashSet :: new ( ) ;
1310+ let mut candidates: Vec < ( Class , Box < dyn Method > ) > = Vec :: new ( ) ;
13091311 while let Some ( interface_name) = interfaces. pop ( ) {
1310- let interface = self . get_class ( & interface_name) ?;
1311- if let Some ( method) = interface. definition . method ( name, descriptor, false ) {
1312- return Some ( ( interface, method) ) ;
1312+ if !visited. insert ( interface_name. clone ( ) ) {
1313+ continue ;
13131314 }
1315+ let interface = self . get_class ( & interface_name) ?;
13141316 interfaces. extend ( interface. definition . interface_names ( ) ) ;
1317+ if let Some ( method) = interface. definition . method ( name, descriptor, false )
1318+ && !method. access_flags ( ) . contains ( MethodAccessFlags :: PRIVATE )
1319+ {
1320+ if candidates
1321+ . iter ( )
1322+ . any ( |( candidate, _) | self . is_inherited_from ( & * candidate. definition , & interface_name) )
1323+ {
1324+ continue ;
1325+ }
1326+ // Keep only declarations not overridden by a more specific interface.
1327+ candidates. retain ( |( candidate, _) | !self . is_inherited_from ( & * interface. definition , & candidate. definition . name ( ) ) ) ;
1328+ candidates. push ( ( interface, method) ) ;
1329+ }
1330+ }
1331+
1332+ let mut concrete = candidates
1333+ . iter ( )
1334+ . enumerate ( )
1335+ . filter ( |( _, ( _, method) ) | !method. access_flags ( ) . contains ( MethodAccessFlags :: ABSTRACT ) ) ;
1336+ if let Some ( ( index, _) ) = concrete. next ( )
1337+ && concrete. next ( ) . is_none ( )
1338+ {
1339+ return Some ( candidates. swap_remove ( index) ) ;
13151340 }
13161341
1317- None
1342+ candidates . into_iter ( ) . next ( )
13181343 }
13191344
13201345 pub ( crate ) fn find_field ( & self , class : & dyn ClassDefinition , name : & str , descriptor : & str ) -> Result < Option < Box < dyn Field > > > {
0 commit comments