From b9d19f254c52fad1899f0d7449e026e7cf2be52b Mon Sep 17 00:00:00 2001
From: Alexis Beingessner
Date: Thu, 28 Jul 2022 14:52:24 -0400
Subject: [PATCH] experiment: de-emphasize signature gunk
---
Cargo.lock | 2 +-
src/ui_processed.rs | 179 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 176 insertions(+), 5 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 8298a16..775a143 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1747,7 +1747,7 @@ dependencies = [
[[package]]
name = "minidump-debugger"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"breakpad-symbols",
"clap 3.2.15",
diff --git a/src/ui_processed.rs b/src/ui_processed.rs
index 02fc64e..fc902c3 100644
--- a/src/ui_processed.rs
+++ b/src/ui_processed.rs
@@ -1,7 +1,10 @@
+use std::ops::Range;
+
use crate::processor::ProcessingStatus;
use crate::{MyApp, Tab};
use eframe::egui;
-use egui::{Color32, ComboBox, Context, FontId, Ui};
+use egui::text::LayoutJob;
+use egui::{Color32, ComboBox, Context, FontId, TextFormat, Ui};
use egui_extras::{Size, StripBuilder, TableBody, TableBuilder};
use minidump_common::utils::basename;
use minidump_processor::{CallStack, ProcessState, StackFrame};
@@ -329,7 +332,34 @@ impl MyApp {
let col5 = {
let mut label = String::new();
crate::frame_signature(&mut label, frame).unwrap();
- fonts.layout(label, font.clone(), Color32::BLACK, col5_width)
+ let fname = &label[..];
+ let parsed = parse_function_name(fname);
+ let parts = [
+ (0..parsed.type_name.start, false),
+ (parsed.type_name.clone(), true),
+ (parsed.type_name.end..parsed.func_name.start, false),
+ (parsed.func_name.clone(), true),
+ (parsed.func_name.end..fname.len(), false),
+ ];
+
+ let mut job = LayoutJob::default();
+ job.wrap.max_width = col5_width;
+ for (range, is_bold) in parts {
+ job.append(
+ &fname[range],
+ 0.0,
+ TextFormat {
+ font_id: font.clone(),
+ color: if is_bold {
+ Color32::BLACK
+ } else {
+ Color32::GRAY
+ },
+ ..Default::default()
+ },
+ );
+ }
+ fonts.layout_job(job)
};
let row_height = col1
@@ -422,8 +452,34 @@ impl MyApp {
fonts.layout(label, font.clone(), Color32::BLACK, col4_width)
};
let col5 = {
- let label = frame.function_name.clone();
- fonts.layout(label, font.clone(), Color32::BLACK, col5_width)
+ let fname = &frame.function_name;
+ let parsed = parse_function_name(fname);
+ let parts = [
+ (0..parsed.type_name.start, false),
+ (parsed.type_name.clone(), true),
+ (parsed.type_name.end..parsed.func_name.start, false),
+ (parsed.func_name.clone(), true),
+ (parsed.func_name.end..fname.len(), false),
+ ];
+
+ let mut job = LayoutJob::default();
+ job.wrap.max_width = col5_width;
+ for (range, is_bold) in parts {
+ job.append(
+ &fname[range],
+ 0.0,
+ TextFormat {
+ font_id: font.clone(),
+ color: if is_bold {
+ Color32::BLACK
+ } else {
+ Color32::GRAY
+ },
+ ..Default::default()
+ },
+ );
+ }
+ fonts.layout_job(job)
};
let row_height = col1
@@ -462,3 +518,118 @@ impl MyApp {
});
}
}
+
+struct ParsedFuncName {
+ type_name: Range,
+ func_name: Range,
+ _args: Vec>,
+}
+
+fn parse_function_name(func: &str) -> ParsedFuncName {
+ let mut gen_depth = 0isize;
+ let mut paren_depth = 0isize;
+ let mut last_saw_colon = false;
+ let mut last_saw_double_colon = false;
+ let mut last_saw_real_char = false;
+
+ let mut cur_piece_start = 0usize;
+ let mut cur_piece_end;
+
+ let mut func_name_start = 0usize;
+ let mut func_name_end = 0usize;
+ let mut type_name_start = 0usize;
+ let mut type_name_end = 0usize;
+
+ for (idx, c) in func.char_indices() {
+ let mut saw_colon = false;
+ let mut saw_real_char = false;
+ let mut gen_adjust = 0isize;
+ let mut paren_adjust = 0isize;
+ match c {
+ '<' => {
+ gen_adjust = 1;
+ }
+ '>' => {
+ assert!(gen_depth > 0, "mismatched generic close!");
+ gen_adjust = -1;
+ }
+ '(' => {
+ paren_adjust = 1;
+ }
+ ')' => {
+ assert!(paren_depth > 0, "mismatched generic close!");
+ paren_adjust = -1;
+ }
+ ':' => {
+ saw_colon = true;
+ }
+ ' ' => {}
+ ',' => {}
+ _ => {
+ saw_real_char = true;
+ }
+ }
+ if saw_real_char {
+ if !last_saw_real_char {
+ cur_piece_start = idx;
+ last_saw_real_char = true;
+ }
+ } else {
+ if last_saw_real_char {
+ cur_piece_end = idx;
+ if gen_depth == 0 && paren_depth == 0 {
+ func_name_start = cur_piece_start;
+ func_name_end = cur_piece_end;
+ }
+ if gen_depth == 1
+ && type_name_start == 0
+ && func_name_start == 0
+ && (c == ' ' || gen_adjust != 0)
+ {
+ type_name_start = cur_piece_start;
+ type_name_end = cur_piece_end;
+ }
+ last_saw_real_char = false;
+ }
+ }
+ if saw_colon {
+ if !last_saw_colon {
+ last_saw_colon = true;
+ } else if !last_saw_double_colon {
+ last_saw_double_colon = true;
+ } else {
+ unreachable!("triple colon???");
+ }
+ } else {
+ last_saw_colon = false;
+ last_saw_double_colon = false;
+ }
+ gen_depth += gen_adjust;
+ paren_depth += paren_adjust;
+ }
+
+ if last_saw_real_char {
+ cur_piece_end = func.len();
+ if gen_depth == 0 && paren_depth == 0 {
+ func_name_start = cur_piece_start;
+ func_name_end = cur_piece_end;
+ }
+ }
+
+ let type_name = type_name_start..type_name_end;
+ let func_name = func_name_start..func_name_end;
+ let args = vec![];
+ ParsedFuncName {
+ type_name,
+ func_name,
+ _args: args,
+ }
+}
+
+#[test]
+fn test_parse_function_name() {
+ let input = r###" as core::iter::traits::collect::Extend>::extend::, ::to_possible_value>, ::possible_values, ::to_possible_value>, clap::builder::possible_value::PossibleValue>::{closure#0}>>"###;
+ let parsed = parse_function_name(input);
+ assert_eq!(&input[parsed.type_name], "Vec");
+ assert_eq!(&input[parsed.func_name], "extend");
+}