Skip to content

Commit 232a9b7

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 b4acde2 commit 232a9b7

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
@@ -1203,6 +1203,7 @@ fn resolve_base_entries<'a>(
12031203
let mut first_no_range_offset: Option<u32> = None;
12041204
// Whether all no-range entries map to the same original method name.
12051205
let mut all_no_range_same_name = true;
1206+
let mut all_no_range_have_line_mapping = true;
12061207
for member in base_entries {
12071208
if member.startline().is_some() {
12081209
if member.original_endline != u32::MAX
@@ -1212,6 +1213,9 @@ fn resolve_base_entries<'a>(
12121213
}
12131214
} else {
12141215
no_range_count += 1;
1216+
if member.original_startline().is_none() {
1217+
all_no_range_have_line_mapping = false;
1218+
}
12151219
match first_no_range_offset {
12161220
None => first_no_range_offset = Some(member.original_name_offset),
12171221
Some(first) if member.original_name_offset != first => {
@@ -1257,6 +1261,12 @@ fn resolve_base_entries<'a>(
12571261
}
12581262
}
12591263

1264+
// Sort no-range frames by original method name when all have line mappings;
1265+
// bare method entries preserve original mapping file order.
1266+
if !all_no_range_same_name && all_no_range_have_line_mapping {
1267+
frames.sort_by(|a, b| a.method.cmp(b.method));
1268+
}
1269+
12601270
frames
12611271
}
12621272

src/mapper.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ fn resolve_base_entries<'s>(
352352
let mut first_no_range_name: Option<&str> = None;
353353
// Whether all no-range entries map to the same original method name.
354354
let mut all_no_range_same_name = true;
355+
let mut all_no_range_have_line_mapping = true;
355356
for member in base_entries {
356357
if member.startline.is_some() {
357358
if member.original_endline.is_some()
@@ -361,6 +362,9 @@ fn resolve_base_entries<'s>(
361362
}
362363
} else {
363364
no_range_count += 1;
365+
if member.original_startline.is_none() {
366+
all_no_range_have_line_mapping = false;
367+
}
364368
match first_no_range_name {
365369
None => first_no_range_name = Some(member.original),
366370
Some(first) if member.original != first => all_no_range_same_name = false,
@@ -404,6 +408,12 @@ fn resolve_base_entries<'s>(
404408
collected.rewrite_rules.extend(member.rewrite_rules.iter());
405409
}
406410
}
411+
412+
// Sort no-range frames by original method name when all have line mappings;
413+
// bare method entries preserve original mapping file order.
414+
if !all_no_range_same_name && all_no_range_have_line_mapping {
415+
collected.frames.sort_by_key(|f| f.method);
416+
}
407417
}
408418

409419
/// A Proguard Remapper.

0 commit comments

Comments
 (0)