diff --git a/ivette/src/frama-c/eva/Values.tsx b/ivette/src/frama-c/eva/Values.tsx index 4925f5252164f89201a09afef007b1930f8be8f9..408bf0b5b01dca92075ac3971c134274ee83b516 100644 --- a/ivette/src/frama-c/eva/Values.tsx +++ b/ivette/src/frama-c/eva/Values.tsx @@ -7,7 +7,7 @@ import React from 'react'; import * as Dome from 'dome'; import { classes } from 'dome/misc/utils'; import { VariableSizeList } from 'react-window'; -import { Vfill, Hpack, Filler } from 'dome/layout/boxes'; +import { Vfill, Hpack, Space, Filler } from 'dome/layout/boxes'; import { Label, Code } from 'dome/controls/labels'; import { IconButton } from 'dome/controls/buttons'; @@ -95,6 +95,23 @@ function ProbeEditor() { ); } +// -------------------------------------------------------------------------- +// --- Stack Panel +// -------------------------------------------------------------------------- + +function StackEditor() { + const model = useModel(); + const callstack = model.getCallstack(); + const visibility = callstack === undefined ? 'hidden' : 'visible'; + return ( + <Hpack style={{ visibility }} className="eva-callinfo"> + <Code className="eva-probe-code"> + {callstack} + </Code> + </Hpack> + ); +} + // -------------------------------------------------------------------------- // --- Table Cell Layout // -------------------------------------------------------------------------- @@ -168,6 +185,7 @@ function TableCell(props: TableCellProps) { const fct = selection?.current?.function; const location = { function: fct, marker: probe.marker }; setSelection({ location }); + model.setSelectedRow(row); } }; const onDoubleClick = () => { @@ -202,8 +220,16 @@ function TableRow(props: TableRowProps) { const row = model.getRow(props.index); if (!row) return null; const { kind, probes } = row; - const className = `eva-${kind}`; const sk = row.stackIndex; + const rowKind = `eva-${kind}`; + const rowParity = sk !== undefined && (sk % 2 === 0); + const rowStyle = + model.isSelectedRow(row) ? 'eva-row-selected' : + rowParity ? 'eva-row-odd' : 'eva-row-even'; + const className = classes( + rowKind, + rowStyle, + ); const header = row.stacks && ( <div className="eva-cell eva-stack"> {sk === undefined ? '#' : `${1 + sk}`} @@ -314,6 +340,7 @@ function ValuesComponent() { )} </AutoSizer> </Vfill> + <StackEditor /> </Vfill> </> ); diff --git a/ivette/src/frama-c/eva/model.ts b/ivette/src/frama-c/eva/model.ts index 8dbe4a460c2f2de6367ac47c79c8276af2233857..b09992ce9b335ed02b1e356402ed3d201367c627 100644 --- a/ivette/src/frama-c/eva/model.ts +++ b/ivette/src/frama-c/eva/model.ts @@ -43,6 +43,7 @@ export class Model implements StateCallbacks { private selected?: Probe; private focused?: Probe; + private callstack?: Values.callstack; private remanent?: Probe; // last transient private probes = new Map<string, Probe>(); @@ -94,6 +95,27 @@ export class Model implements StateCallbacks { return row ? row.hlines : 0; } + setSelectedRow(row: Row) { + const cs = row.callstack; + if (cs !== this.callstack) { + this.callstack = cs; + this.forceUpdate(); + } + } + + isSelectedRow(row: Row): boolean { + const cs = this.callstack; + return cs !== undefined ? cs === row.callstack : false; + } + + getCallstack(): string | undefined { + const p = this.selected; + const c = this.callstack; + if (p && c) return `${p.stmt}::${c}`; + if (p) return p.stmt; + return undefined; + } + // --- Throttled setLayout(ly: ModelLayout) { if (!equal(this.layout, ly)) { @@ -112,9 +134,11 @@ export class Model implements StateCallbacks { const s = this.selected; if (!s) { this.focused = undefined; + this.callstack = undefined; this.remanent = undefined; } else if (s.loading) { this.focused = undefined; + this.callstack = undefined; } else { this.focused = s; if (s.code) { @@ -145,6 +169,7 @@ export class Model implements StateCallbacks { this.focused = undefined; this.remanent = undefined; this.selected = undefined; + this.callstack = undefined; this.probes.clear(); this.stacks.clear(); this.values.clear(); diff --git a/ivette/src/frama-c/eva/style.css b/ivette/src/frama-c/eva/style.css index 738cfe2dc9a08965ecce2a809f8e5ed353661599..920974dce2b82ece3168752d3225d1723820370b 100644 --- a/ivette/src/frama-c/eva/style.css +++ b/ivette/src/frama-c/eva/style.css @@ -14,15 +14,18 @@ /* -------------------------------------------------------------------------- */ .eva-probe { - margin: 8px; + padding-left: 6px; + padding-top: 2px; + padding-bottom: 4px; width: 100%; + background: #ccc; display: flex; } .eva-probe-label { flex: 0 1 auto; min-width: 22px; - text-align: right; + text-align: left; } .eva-probe-code { @@ -61,7 +64,7 @@ flex: 0 1 auto; height: 100%; border-bottom: thin solid black; - border-right: thin solid black; + border-left: thin solid black; } .eva-probes .eva-row { @@ -81,11 +84,11 @@ .eva-cell { flex: 1 1 auto; - border-left: thin solid black; + border-right: thin solid black; } .eva-cell:nth-child(last) { - border-left: none; + border-right: none; } .eva-probes .eva-cell { @@ -93,6 +96,17 @@ text-align: center; } +/* -------------------------------------------------------------------------- */ +/* --- Call Satck Info --- */ +/* -------------------------------------------------------------------------- */ + +.eva-callinfo { + width: 100%; + background: #ccc; + padding-top: 2px; + padding-left: 12px; +} + /* -------------------------------------------------------------------------- */ /* --- Table Rows Background --- */ /* -------------------------------------------------------------------------- */ @@ -102,15 +116,31 @@ } .eva-values .eva-row { - background: #fff; + background: #eee; } -.eva-callstack .eva-row:nth-child(odd) { - background: #d8edef; +.eva-callstack.eva-row-odd .eva-row { + background: #eee; } -.eva-callsatck .eva-row:nth-child(even) { - background: #fff; +.eva-callstack.eva-row-even .eva-row { + background: #e2e8e8; +} + +.eva-callstack.eva-row-odd .eva-row .eva-transient { + background: #fff0d5; +} + +.eva-callstack.eva-row-even .eva-row .eva-transient { + background: #fff0d5; +} + +.eva-callstack.eva-row-selected .eva-row .eva-transient { + background: lightblue; +} + +.eva-callstack.eva-row-selected .eva-row { + background: lightblue; } .eva-probes .eva-transient { @@ -125,12 +155,12 @@ background: lightblue; } -.eva-values .eva-focused { - background: #def6ff; +.eva-stack { + background: #eee; } -.eva-cell.eva-stack { - background: #eee; +.eva-callstack.eva-row-selected .eva-stack { + background: lightblue; } /* -------------------------------------------------------------------------- */