mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 07:03:39 +00:00
Add hover/context APIs to wasm component
This commit is contained in:
parent
2eafbb218b
commit
48305e0380
@ -25,10 +25,11 @@ use exports::objdiff::core::{
|
||||
GuestObjectDiff, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
|
||||
},
|
||||
display::{
|
||||
ContextMenuItem, DiffText, DiffTextColor, DiffTextOpcode, DiffTextSegment, DiffTextSymbol,
|
||||
DisplayConfig, Guest as GuestDisplay, HoverItem, InstructionDiffKind, InstructionDiffRow,
|
||||
SectionDisplay, SectionDisplaySymbol, SymbolDisplay, SymbolFilter, SymbolFlags, SymbolKind,
|
||||
SymbolRef,
|
||||
ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode,
|
||||
DiffTextSegment, DiffTextSymbol, DisplayConfig, Guest as GuestDisplay, HoverItem,
|
||||
HoverItemColor, HoverItemText, InstructionDiffKind, InstructionDiffRow, SectionDisplay,
|
||||
SectionDisplaySymbol, SymbolDisplay, SymbolFilter, SymbolFlags, SymbolKind,
|
||||
SymbolNavigationKind, SymbolRef,
|
||||
},
|
||||
};
|
||||
|
||||
@ -86,10 +87,6 @@ impl GuestDiff for Component {
|
||||
}
|
||||
|
||||
impl GuestDisplay for Component {
|
||||
fn symbol_context(_obj: ObjectBorrow, _symbol: SymbolRef) -> Vec<ContextMenuItem> { todo!() }
|
||||
|
||||
fn symbol_hover(_obj: ObjectBorrow, _symbol: SymbolRef) -> Vec<HoverItem> { todo!() }
|
||||
|
||||
fn display_sections(
|
||||
diff: ObjectDiffBorrow,
|
||||
filter: SymbolFilter,
|
||||
@ -202,6 +199,102 @@ impl GuestDisplay for Component {
|
||||
.unwrap();
|
||||
InstructionDiffRow { segments, diff_kind: InstructionDiffKind::from(row.kind) }
|
||||
}
|
||||
|
||||
fn symbol_context(
|
||||
diff: ObjectDiffBorrow,
|
||||
symbol_display: SectionDisplaySymbol,
|
||||
) -> Vec<ContextItem> {
|
||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||
let obj = obj_diff.0.as_ref();
|
||||
diff::display::symbol_context(obj, symbol_display.symbol as usize)
|
||||
.into_iter()
|
||||
.map(|item| ContextItem::from(item))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn symbol_hover(
|
||||
diff: ObjectDiffBorrow,
|
||||
symbol_display: SectionDisplaySymbol,
|
||||
) -> Vec<HoverItem> {
|
||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||
let obj = obj_diff.0.as_ref();
|
||||
diff::display::symbol_hover(obj, symbol_display.symbol as usize, 0 /* TODO */)
|
||||
.into_iter()
|
||||
.map(|item| HoverItem::from(item))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn instruction_context(
|
||||
diff: ObjectDiffBorrow,
|
||||
symbol_display: SectionDisplaySymbol,
|
||||
row_index: u32,
|
||||
diff_config: DiffConfigBorrow,
|
||||
) -> Result<Vec<ContextItem>, String> {
|
||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||
let obj = obj_diff.0.as_ref();
|
||||
let obj_diff = &obj_diff.1;
|
||||
let symbol_idx = symbol_display.symbol as usize;
|
||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||
obj_diff
|
||||
.mapping_symbols
|
||||
.iter()
|
||||
.find(|s| s.symbol_index == symbol_idx)
|
||||
.map(|s| &s.symbol_diff)
|
||||
.unwrap()
|
||||
} else {
|
||||
&obj_diff.symbols[symbol_idx]
|
||||
};
|
||||
let row = &symbol_diff.instruction_rows[row_index as usize];
|
||||
let Some(ins_ref) = row.ins_ref else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
|
||||
return Err("Failed to resolve instruction".into());
|
||||
};
|
||||
let ins =
|
||||
obj.arch.process_instruction(resolved, &diff_config).map_err(|e| e.to_string())?;
|
||||
Ok(diff::display::instruction_context(obj, resolved, &ins)
|
||||
.into_iter()
|
||||
.map(|item| ContextItem::from(item))
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn instruction_hover(
|
||||
diff: ObjectDiffBorrow,
|
||||
symbol_display: SectionDisplaySymbol,
|
||||
row_index: u32,
|
||||
diff_config: DiffConfigBorrow,
|
||||
) -> Result<Vec<HoverItem>, String> {
|
||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||
let obj = obj_diff.0.as_ref();
|
||||
let obj_diff = &obj_diff.1;
|
||||
let symbol_idx = symbol_display.symbol as usize;
|
||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||
obj_diff
|
||||
.mapping_symbols
|
||||
.iter()
|
||||
.find(|s| s.symbol_index == symbol_idx)
|
||||
.map(|s| &s.symbol_diff)
|
||||
.unwrap()
|
||||
} else {
|
||||
&obj_diff.symbols[symbol_idx]
|
||||
};
|
||||
let row = &symbol_diff.instruction_rows[row_index as usize];
|
||||
let Some(ins_ref) = row.ins_ref else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
|
||||
return Err("Failed to resolve instruction".into());
|
||||
};
|
||||
let ins =
|
||||
obj.arch.process_instruction(resolved, &diff_config).map_err(|e| e.to_string())?;
|
||||
Ok(diff::display::instruction_hover(obj, resolved, &ins)
|
||||
.into_iter()
|
||||
.map(|item| HoverItem::from(item))
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<obj::SymbolKind> for SymbolKind {
|
||||
@ -342,4 +435,52 @@ impl GuestObjectDiff for ResourceObjectDiff {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diff::display::HoverItem> for HoverItem {
|
||||
fn from(item: diff::display::HoverItem) -> Self {
|
||||
match item {
|
||||
diff::display::HoverItem::Text { label, value, color } => {
|
||||
HoverItem::Text(HoverItemText { label, value, color: HoverItemColor::from(color) })
|
||||
}
|
||||
diff::display::HoverItem::Separator => HoverItem::Separator,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diff::display::HoverItemColor> for HoverItemColor {
|
||||
fn from(color: diff::display::HoverItemColor) -> Self {
|
||||
match color {
|
||||
diff::display::HoverItemColor::Normal => HoverItemColor::Normal,
|
||||
diff::display::HoverItemColor::Emphasized => HoverItemColor::Emphasized,
|
||||
diff::display::HoverItemColor::Special => HoverItemColor::Special,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diff::display::ContextItem> for ContextItem {
|
||||
fn from(item: diff::display::ContextItem) -> Self {
|
||||
match item {
|
||||
diff::display::ContextItem::Copy { value, label } => {
|
||||
ContextItem::Copy(ContextItemCopy { value, label })
|
||||
}
|
||||
diff::display::ContextItem::Navigate { label, symbol_index, kind } => {
|
||||
ContextItem::Navigate(ContextItemNavigate {
|
||||
label,
|
||||
symbol: symbol_index as SymbolRef,
|
||||
kind: SymbolNavigationKind::from(kind),
|
||||
})
|
||||
}
|
||||
diff::display::ContextItem::Separator => ContextItem::Separator,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diff::display::SymbolNavigationKind> for SymbolNavigationKind {
|
||||
fn from(kind: diff::display::SymbolNavigationKind) -> Self {
|
||||
match kind {
|
||||
diff::display::SymbolNavigationKind::Normal => SymbolNavigationKind::Normal,
|
||||
diff::display::SymbolNavigationKind::Extab => SymbolNavigationKind::Extab,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export!(Component);
|
||||
|
@ -108,18 +108,26 @@ interface display {
|
||||
row-count: u32,
|
||||
}
|
||||
|
||||
record context-menu-item-copy {
|
||||
enum symbol-navigation-kind {
|
||||
normal,
|
||||
extab,
|
||||
}
|
||||
|
||||
record context-item-copy {
|
||||
value: string,
|
||||
label: option<string>,
|
||||
}
|
||||
|
||||
record context-menu-item-navigate {
|
||||
record context-item-navigate {
|
||||
label: string,
|
||||
symbol: symbol-ref,
|
||||
kind: symbol-navigation-kind,
|
||||
}
|
||||
|
||||
variant context-menu-item {
|
||||
copy(context-menu-item-copy),
|
||||
navigate(context-menu-item-navigate),
|
||||
variant context-item {
|
||||
copy(context-item-copy),
|
||||
navigate(context-item-navigate),
|
||||
separator,
|
||||
}
|
||||
|
||||
enum hover-item-color {
|
||||
@ -128,11 +136,17 @@ interface display {
|
||||
special,
|
||||
}
|
||||
|
||||
record hover-item {
|
||||
text: string,
|
||||
record hover-item-text {
|
||||
label: string,
|
||||
value: string,
|
||||
color: hover-item-color,
|
||||
}
|
||||
|
||||
variant hover-item {
|
||||
text(hover-item-text),
|
||||
separator,
|
||||
}
|
||||
|
||||
record diff-text-opcode {
|
||||
mnemonic: string,
|
||||
opcode: u16,
|
||||
@ -216,22 +230,36 @@ interface display {
|
||||
symbol: section-display-symbol,
|
||||
) -> symbol-display;
|
||||
|
||||
symbol-context: func(
|
||||
object: borrow<object>,
|
||||
symbol: symbol-ref,
|
||||
) -> list<context-menu-item>;
|
||||
|
||||
symbol-hover: func(
|
||||
object: borrow<object>,
|
||||
symbol: symbol-ref,
|
||||
) -> list<hover-item>;
|
||||
|
||||
display-instruction-row: func(
|
||||
diff: borrow<object-diff>,
|
||||
symbol: section-display-symbol,
|
||||
row-index: u32,
|
||||
config: borrow<diff-config>,
|
||||
) -> instruction-diff-row;
|
||||
|
||||
symbol-context: func(
|
||||
diff: borrow<object-diff>,
|
||||
symbol: section-display-symbol,
|
||||
) -> list<context-item>;
|
||||
|
||||
symbol-hover: func(
|
||||
diff: borrow<object-diff>,
|
||||
symbol: section-display-symbol,
|
||||
) -> list<hover-item>;
|
||||
|
||||
instruction-context: func(
|
||||
diff: borrow<object-diff>,
|
||||
symbol: section-display-symbol,
|
||||
row-index: u32,
|
||||
config: borrow<diff-config>,
|
||||
) -> result<list<context-item>, string>;
|
||||
|
||||
instruction-hover: func(
|
||||
diff: borrow<object-diff>,
|
||||
symbol: section-display-symbol,
|
||||
row-index: u32,
|
||||
config: borrow<diff-config>,
|
||||
) -> result<list<hover-item>, string>;
|
||||
}
|
||||
|
||||
world api {
|
||||
|
Loading…
x
Reference in New Issue
Block a user