From 77392ed51ed4d6affc76e75bef8c8a7ab3457d49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr>
Date: Fri, 18 Dec 2020 10:28:43 +0100
Subject: [PATCH] [ivette/eva] fix function & callstack selection

---
 ivette/src/frama-c/eva/Values.tsx | 16 ++++++++-------
 ivette/src/frama-c/eva/model.ts   | 33 +++++++++++++++++--------------
 ivette/src/frama-c/eva/probes.ts  |  4 +++-
 ivette/src/frama-c/eva/style.css  | 14 ++++++++-----
 4 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/ivette/src/frama-c/eva/Values.tsx b/ivette/src/frama-c/eva/Values.tsx
index 9ab06cb22a9..31660273749 100644
--- a/ivette/src/frama-c/eva/Values.tsx
+++ b/ivette/src/frama-c/eva/Values.tsx
@@ -69,6 +69,7 @@ function ProbeInfos() {
   const probe = model.getFocused();
   const transient = probe?.transient ?? false;
   const label = probe?.label;
+  const fct = probe?.fct;
   const code = probe?.code;
   const stmt = probe?.stmt;
   const rank = probe?.rank;
@@ -88,7 +89,7 @@ function ProbeInfos() {
       <div style={{ minWidth: width, height }} className="eva-probeinfo-code">
         <SizedArea cols={cols} rows={rows}>{code}</SizedArea>
       </div>
-      <Code><Stmt stmt={stmt} rank={rank} /></Code>
+      <Code>{fct}<Stmt stmt={stmt} rank={rank} /></Code>
       <IconButton
         className="eva-probeinfo-button"
         display={stackable}
@@ -164,7 +165,7 @@ const CELLPADDING = 12;
 
 function TableCell(props: TableCellProps) {
   const model = useModel();
-  const [selection, setSelection] = States.useSelection();
+  const [, setSelection] = States.useSelection();
   const { probe, row } = props;
   const { kind, callstack } = row;
   const minWidth = CELLPADDING + WSIZER.dimension(probe.minCols);
@@ -216,12 +217,11 @@ function TableCell(props: TableCellProps) {
   const className = classes(
     'eva-cell',
     transient && 'eva-transient',
-    !transient && isFocused && 'eva-focused',
+    isFocused && 'eva-focused',
   );
   const onClick = () => {
     if (probe) {
-      const fct = selection?.current?.function;
-      const location = { function: fct, marker: probe.marker };
+      const location = { function: probe.fct, marker: probe.marker };
       setSelection({ location });
       model.setSelectedRow(row);
     }
@@ -326,8 +326,10 @@ function ValuesPanel(props: ValuesPanelProps) {
   const rowHeight = HSIZER.dimension(1);
   const [selection] = States.useSelection();
   React.useEffect(() => {
-    const target = Ast.jMarker(selection?.current?.marker);
-    model.setLayout({ zoom, margin, target });
+    const curr = selection?.current;
+    const fct = curr?.function;
+    const marker = Ast.jMarker(curr?.marker);
+    model.setLayout({ zoom, margin, fct, marker });
   });
   // --- render list
   return (
diff --git a/ivette/src/frama-c/eva/model.ts b/ivette/src/frama-c/eva/model.ts
index 0b825e10ad4..6023adb04ac 100644
--- a/ivette/src/frama-c/eva/model.ts
+++ b/ivette/src/frama-c/eva/model.ts
@@ -18,7 +18,8 @@ import { StateCallbacks, ValueCache } from './cells';
 import { LayoutProps, LayoutEngine, Row } from './layout';
 
 export interface ModelLayout extends LayoutProps {
-  target?: Ast.marker;
+  fct?: string;
+  marker?: Ast.marker;
 }
 
 /* --------------------------------------------------------------------------*/
@@ -51,10 +52,10 @@ export class Model implements StateCallbacks {
   isFocused(p: Probe | undefined) { return this.focused === p; }
   isRemanent(p: Probe | undefined) { return this.remanent === p; }
 
-  getProbe(m: Ast.marker): Probe {
+  getProbe(fct: string, m: Ast.marker): Probe {
     let p = this.probes.get(m);
     if (!p) {
-      p = new Probe(this, m);
+      p = new Probe(this, fct, m);
       this.probes.set(m, p);
       p.requestProbeInfo();
     }
@@ -110,18 +111,16 @@ export class Model implements StateCallbacks {
 
   getCallstack(): Callsite[] {
     const c = this.callstack;
-    if (c !== undefined) return this.stacks.getCalls(c);
-    const [s] = this.getStacks(this.focused);
-    if (s !== undefined) return this.stacks.getCalls(s);
-    return [];
+    return c === undefined ? [] : this.stacks.getCalls(c);
   }
 
   // --- Throttled
   setLayout(ly: ModelLayout) {
     if (!equal(this.layout, ly)) {
       this.layout = ly;
-      const target = Ast.jMarker(ly.target);
-      this.selected = target ? this.getProbe(target) : undefined;
+      const { fct, marker } = ly;
+      this.selected =
+        fct && marker ? this.getProbe(fct, marker) : undefined;
       this.forceLayout();
     }
   }
@@ -136,13 +135,17 @@ export class Model implements StateCallbacks {
       this.focused = undefined;
       this.callstack = undefined;
       this.remanent = undefined;
-    } else if (s.loading) {
-      this.focused = undefined;
-      this.callstack = undefined;
-    } else {
+    } else if (!s.loading) {
       this.focused = s;
-      if (s.code) {
-        if (s.transient) this.remanent = s;
+      const stacks = this.getStacks(s);
+      if (s.byCallstacks) {
+        const cs0 = this.callstack;
+        if (cs0) this.callstack = stacks.find((cs) => cs === cs0);
+      } else {
+        this.callstack = stacks.length === 1 ? stacks[0] : undefined;
+      }
+      if (s.code && s.transient) {
+        this.remanent = s;
       } else {
         this.remanent = undefined;
       }
diff --git a/ivette/src/frama-c/eva/probes.ts b/ivette/src/frama-c/eva/probes.ts
index bd8a561d090..a77c9897711 100644
--- a/ivette/src/frama-c/eva/probes.ts
+++ b/ivette/src/frama-c/eva/probes.ts
@@ -43,6 +43,7 @@ function newLabel() {
 export class Probe {
 
   // properties
+  readonly fct: string;
   readonly marker: Ast.marker;
   readonly state: StateCallbacks;
   transient = true;
@@ -57,7 +58,8 @@ export class Probe {
   zoomed = false;
   zoomable = false;
 
-  constructor(state: StateCallbacks, marker: Ast.marker) {
+  constructor(state: StateCallbacks, fct: string, marker: Ast.marker) {
+    this.fct = fct;
     this.marker = marker;
     this.state = state;
     this.requestProbeInfo = this.requestProbeInfo.bind(this);
diff --git a/ivette/src/frama-c/eva/style.css b/ivette/src/frama-c/eva/style.css
index 575b5f587f4..e970cbd5216 100644
--- a/ivette/src/frama-c/eva/style.css
+++ b/ivette/src/frama-c/eva/style.css
@@ -121,6 +121,10 @@
     padding-right: 7px;
 }
 
+.eva-callsite {
+    cursor: default;
+}
+
 /* -------------------------------------------------------------------------- */
 /* --- Table Rows Background                                              --- */
 /* -------------------------------------------------------------------------- */
@@ -157,16 +161,16 @@
     background: lightblue;
 }
 
-.eva-probes .eva-transient {
-    background: orange;
+.eva-probes .eva-focused {
+    background: #02da02;
 }
 
-.eva-values .eva-transient {
+.eva-probes .eva-transient {
     background: #fff0d5;
 }
 
-.eva-probes .eva-focused {
-    background: lightblue;
+.eva-probes .eva-transient.eva-focused {
+    background: orange;
 }
 
 .eva-stack {
-- 
GitLab