Restructure diffing code & initial 3-way diffing (WIP)

This commit is contained in:
2024-03-18 18:10:18 -06:00
parent 1343f4fd2b
commit 3c74b89f15
17 changed files with 957 additions and 487 deletions

View File

@@ -5,7 +5,10 @@ use egui::{
SelectableLabel, TextEdit, Ui, Vec2, Widget,
};
use egui_extras::{Size, StripBuilder};
use objdiff_core::obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags};
use objdiff_core::{
diff::{ObjDiff, ObjSymbolDiff},
obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags},
};
use crate::{
app::AppConfigRef,
@@ -17,7 +20,7 @@ use crate::{
views::{appearance::Appearance, function_diff::FunctionViewState, write_text},
};
pub struct SymbolReference {
pub struct SymbolRefByName {
pub symbol_name: String,
pub demangled_symbol_name: Option<String>,
pub section_name: String,
@@ -50,7 +53,7 @@ pub struct DiffViewState {
#[derive(Default)]
pub struct SymbolViewState {
pub highlighted_symbol: Option<String>,
pub selected_symbol: Option<SymbolReference>,
pub selected_symbol: Option<SymbolRefByName>,
pub reverse_fn_order: bool,
pub disable_reverse_fn_order: bool,
pub show_hidden_symbols: bool,
@@ -180,6 +183,7 @@ fn symbol_hover_ui(ui: &mut Ui, symbol: &ObjSymbol, appearance: &Appearance) {
fn symbol_ui(
ui: &mut Ui,
symbol: &ObjSymbol,
symbol_diff: &ObjSymbolDiff,
section: Option<&ObjSection>,
state: &mut SymbolViewState,
appearance: &Appearance,
@@ -210,7 +214,7 @@ fn symbol_ui(
write_text("h", appearance.deemphasized_text_color, &mut job, appearance.code_font.clone());
}
write_text("] ", appearance.text_color, &mut job, appearance.code_font.clone());
if let Some(match_percent) = symbol.match_percent {
if let Some(match_percent) = symbol_diff.match_percent {
write_text("(", appearance.text_color, &mut job, appearance.code_font.clone());
write_text(
&format!("{match_percent:.0}%"),
@@ -228,14 +232,14 @@ fn symbol_ui(
if response.clicked() {
if let Some(section) = section {
if section.kind == ObjSectionKind::Code {
state.selected_symbol = Some(SymbolReference {
state.selected_symbol = Some(SymbolRefByName {
symbol_name: symbol.name.clone(),
demangled_symbol_name: symbol.demangled_name.clone(),
section_name: section.name.clone(),
});
ret = Some(View::FunctionDiff);
} else if section.kind == ObjSectionKind::Data {
state.selected_symbol = Some(SymbolReference {
state.selected_symbol = Some(SymbolRefByName {
symbol_name: section.name.clone(),
demangled_symbol_name: None,
section_name: section.name.clone(),
@@ -262,7 +266,7 @@ fn symbol_matches_search(symbol: &ObjSymbol, search_str: &str) -> bool {
#[must_use]
fn symbol_list_ui(
ui: &mut Ui,
obj: &ObjInfo,
obj: &(ObjInfo, ObjDiff),
state: &mut SymbolViewState,
lower_search: &str,
appearance: &Appearance,
@@ -273,34 +277,50 @@ fn symbol_list_ui(
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
ui.style_mut().wrap = Some(false);
if !obj.common.is_empty() {
if !obj.0.common.is_empty() {
CollapsingHeader::new(".comm").default_open(true).show(ui, |ui| {
for symbol in &obj.common {
ret = ret.or(symbol_ui(ui, symbol, None, state, appearance));
for (symbol, symbol_diff) in obj.0.common.iter().zip(&obj.1.common) {
ret = ret.or(symbol_ui(ui, symbol, symbol_diff, None, state, appearance));
}
});
}
for section in &obj.sections {
for (section, section_diff) in obj.0.sections.iter().zip(&obj.1.sections) {
CollapsingHeader::new(format!("{} ({:x})", section.name, section.size))
.id_source(Id::new(section.name.clone()).with(section.index))
.default_open(true)
.show(ui, |ui| {
if section.kind == ObjSectionKind::Code && state.reverse_fn_order {
for symbol in section.symbols.iter().rev() {
for (symbol, symbol_diff) in
section.symbols.iter().zip(&section_diff.symbols).rev()
{
if !symbol_matches_search(symbol, lower_search) {
continue;
}
ret =
ret.or(symbol_ui(ui, symbol, Some(section), state, appearance));
ret = ret.or(symbol_ui(
ui,
symbol,
symbol_diff,
Some(section),
state,
appearance,
));
}
} else {
for symbol in &section.symbols {
for (symbol, symbol_diff) in
section.symbols.iter().zip(&section_diff.symbols)
{
if !symbol_matches_search(symbol, lower_search) {
continue;
}
ret =
ret.or(symbol_ui(ui, symbol, Some(section), state, appearance));
ret = ret.or(symbol_ui(
ui,
symbol,
symbol_diff,
Some(section),
state,
appearance,
));
}
}
});