Skip to content

Commit 399ec14

Browse files
romtsnclaude
andcommitted
feat(r8): Sort ambiguous no-range entries alphabetically by method name
When multiple no-range entries with different original method names all have line mappings, sort them alphabetically. Bare method entries (no line mapping) preserve original mapping file order. Fixes test_single_line_no_line_number_stacktrace — all 10 R8 line number handling tests now pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ea0879b commit 399ec14

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

src/cache/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,7 @@ fn resolve_base_entries<'a>(
12141214
let mut first_no_range_offset: Option<u32> = None;
12151215
// Whether all no-range entries map to the same original method name.
12161216
let mut all_no_range_same_name = true;
1217+
let mut all_no_range_have_line_mapping = true;
12171218
for member in base_entries {
12181219
if member.startline().is_some() {
12191220
if member.original_endline != u32::MAX
@@ -1223,6 +1224,9 @@ fn resolve_base_entries<'a>(
12231224
}
12241225
} else {
12251226
no_range_count += 1;
1227+
if member.original_startline().is_none() {
1228+
all_no_range_have_line_mapping = false;
1229+
}
12261230
match first_no_range_offset {
12271231
None => first_no_range_offset = Some(member.original_name_offset),
12281232
Some(first) if member.original_name_offset != first => {
@@ -1268,6 +1272,12 @@ fn resolve_base_entries<'a>(
12681272
}
12691273
}
12701274

1275+
// Sort no-range frames by original method name when all have line mappings;
1276+
// bare method entries preserve original mapping file order.
1277+
if !all_no_range_same_name && all_no_range_have_line_mapping {
1278+
frames.sort_by(|a, b| a.method.cmp(b.method));
1279+
}
1280+
12711281
frames
12721282
}
12731283

src/mapper.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ fn resolve_base_entries<'s>(
361361
let mut first_no_range_name: Option<&str> = None;
362362
// Whether all no-range entries map to the same original method name.
363363
let mut all_no_range_same_name = true;
364+
let mut all_no_range_have_line_mapping = true;
364365
for member in base_entries {
365366
if member.startline.is_some() {
366367
if member.original_endline.is_some()
@@ -370,6 +371,9 @@ fn resolve_base_entries<'s>(
370371
}
371372
} else {
372373
no_range_count += 1;
374+
if member.original_startline.is_none() {
375+
all_no_range_have_line_mapping = false;
376+
}
373377
match first_no_range_name {
374378
None => first_no_range_name = Some(member.original),
375379
Some(first) if member.original != first => all_no_range_same_name = false,
@@ -413,6 +417,12 @@ fn resolve_base_entries<'s>(
413417
collected.rewrite_rules.extend(member.rewrite_rules.iter());
414418
}
415419
}
420+
421+
// Sort no-range frames by original method name when all have line mappings;
422+
// bare method entries preserve original mapping file order.
423+
if !all_no_range_same_name && all_no_range_have_line_mapping {
424+
collected.frames.sort_by_key(|f| f.method);
425+
}
416426
}
417427

418428
/// A Proguard Remapper.

0 commit comments

Comments
 (0)