@@ -440,3 +440,36 @@ fn test_method_with_zero_zero_and_line_specific_mappings() {
440440 assert_eq ! ( frame. line( ) , 70 ) ;
441441 assert_eq ! ( mapped. next( ) , None ) ;
442442}
443+
444+ #[ test]
445+ fn test_method_with_zero_zero_and_line_specific_mappings_cache ( ) {
446+ // Test case where a method has both 0:0: mappings and line-specific mappings.
447+ // The AndroidShadowContext class has method 'b' (obfuscated) with:
448+ // - 0:0: mapping pointing to line 68
449+ // - 1:4: mapping pointing to line 70
450+ // - 5:7: mapping pointing to line 71
451+ // etc.
452+ // When remapping a frame with line 3, it should match the 1:4: mapping (line 70),
453+ // NOT the 0:0: mapping (line 68), because we skip 0:0: mappings when line-specific
454+ // mappings exist.
455+ let mapping = ProguardMapping :: new ( MAPPING_ZERO_LINE_INFO ) ;
456+ let mut buf = Vec :: new ( ) ;
457+ ProguardCache :: write ( & mapping, & mut buf) . unwrap ( ) ;
458+ let cache = ProguardCache :: parse ( & buf) . unwrap ( ) ;
459+ cache. test ( ) ;
460+
461+ // Remap frame with method 'b' at line 3
462+ // This should match the 1:4: mapping (line 3 is in range 1-4) -> original line 70
463+ let frame = StackFrame :: new ( "h2.a" , "b" , 3 ) ;
464+ let mut mapped = cache. remap_frame ( & frame) ;
465+
466+ let remapped_frame = mapped. next ( ) . unwrap ( ) ;
467+ assert_eq ! (
468+ remapped_frame. class( ) ,
469+ "androidx.compose.ui.graphics.shadow.AndroidShadowContext"
470+ ) ;
471+ assert_eq ! ( remapped_frame. method( ) , "obtainDropShadowRenderer-eZhPAX0" ) ;
472+ // Should map to line 70 (from the 1:4: mapping), not line 68 (from the 0:0: mapping)
473+ assert_eq ! ( remapped_frame. line( ) , 70 ) ;
474+ assert_eq ! ( mapped. next( ) , None ) ;
475+ }
0 commit comments