Skip to content

Commit 82d62e3

Browse files
committed
Preserve input lineno when no mapping is available
1 parent 5979252 commit 82d62e3

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

src/cache/mod.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,8 @@ impl<'r, 'data> RemappedFrameIter<'r, 'data> {
909909
class,
910910
method,
911911
file,
912-
line: 0,
912+
// Preserve input line if present when the mapping has no line info.
913+
line: frame.line,
913914
parameters: frame.parameters,
914915
method_synthesized: first_base.is_synthesized(),
915916
});
@@ -945,7 +946,8 @@ impl<'r, 'data> RemappedFrameIter<'r, 'data> {
945946
class,
946947
method,
947948
file,
948-
line: 0,
949+
// Preserve input line if present when the mapping has no line info.
950+
line: frame.line,
949951
parameters: frame.parameters,
950952
method_synthesized: first.is_synthesized(),
951953
});
@@ -1005,6 +1007,26 @@ fn iterate_with_lines<'a>(
10051007
if has_line_info && frame.line > 0 && member.endline == 0 {
10061008
continue;
10071009
}
1010+
// If the mapping entry has no line range, preserve the input line number (if any).
1011+
if member.endline == 0 {
1012+
let class = cache
1013+
.read_string(member.original_class_offset)
1014+
.unwrap_or(frame.class);
1015+
1016+
let method = cache.read_string(member.original_name_offset).ok()?;
1017+
1018+
// Synthesize from class name (input filename is not reliable)
1019+
let file = synthesize_source_file(class, outer_source_file).map(Cow::Owned);
1020+
1021+
return Some(StackFrame {
1022+
class,
1023+
method,
1024+
file,
1025+
line: frame.line,
1026+
parameters: frame.parameters,
1027+
method_synthesized: member.is_synthesized(),
1028+
});
1029+
}
10081030
// skip any members which do not match our frames line
10091031
if member.endline > 0
10101032
&& (frame.line < member.startline as usize || frame.line > member.endline as usize)
@@ -1080,7 +1102,8 @@ fn iterate_without_lines_preferring_base<'a>(
10801102
class,
10811103
method,
10821104
file,
1083-
line: 0,
1105+
// Preserve input line if present when the mapping has no line info.
1106+
line: frame.line,
10841107
parameters: frame.parameters,
10851108
method_synthesized: member.is_synthesized(),
10861109
});
@@ -1109,7 +1132,8 @@ fn iterate_without_lines<'a>(
11091132
class,
11101133
method,
11111134
file,
1112-
line: 0,
1135+
// Preserve input line if present when the mapping has no line info.
1136+
line: frame.line,
11131137
parameters: frame.parameters,
11141138
method_synthesized: member.is_synthesized(),
11151139
})

src/mapper.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ fn map_member_without_lines<'a>(
224224
class,
225225
method: member.original,
226226
file,
227-
line: 0,
227+
// Preserve input line if present (e.g. "Unknown Source:7") when the mapping itself
228+
// has no line information. This matches R8 retrace behavior.
229+
line: frame.line,
228230
parameters: frame.parameters,
229231
method_synthesized: member.is_synthesized,
230232
}
@@ -272,6 +274,10 @@ fn iterate_with_lines<'a>(
272274
if has_line_info && frame.line > 0 && member.endline == 0 {
273275
continue;
274276
}
277+
// If the mapping entry has no line range, preserve the input line number (if any).
278+
if member.endline == 0 {
279+
return Some(map_member_without_lines(frame, member));
280+
}
275281
if let Some(mapped) = map_member_with_lines(frame, member) {
276282
return Some(mapped);
277283
}
@@ -596,7 +602,12 @@ impl<'s> ProguardMapper<'s> {
596602
if has_line_info && member.endline == 0 {
597603
continue;
598604
}
599-
if let Some(mapped) = map_member_with_lines(&frame, member) {
605+
if member.endline == 0 {
606+
collected
607+
.frames
608+
.push(map_member_without_lines(&frame, member));
609+
collected.rewrite_rules.extend(member.rewrite_rules.iter());
610+
} else if let Some(mapped) = map_member_with_lines(&frame, member) {
600611
collected.frames.push(mapped);
601612
collected.rewrite_rules.extend(member.rewrite_rules.iter());
602613
}

tests/retrace.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ fn test_remap_no_lines() {
7171
let mut mapped = mapper.remap_frame(&StackFrame::new("a", "b", 10));
7272
assert_eq!(
7373
mapped.next().unwrap(),
74-
StackFrame::with_file("original.class.name", "originalMethodName", 0, "name.java")
74+
// Preserve input line number when the mapping has no line information.
75+
StackFrame::with_file("original.class.name", "originalMethodName", 10, "name.java")
7576
);
7677
assert_eq!(mapped.next(), None);
7778
}

0 commit comments

Comments
 (0)