diff --git a/ivette/api/plugins/dive/index.ts b/ivette/api/plugins/dive/index.ts index a63a701b04eb6ea0516c8cea456b014f3df5c3c7..b1e2c48ddcccd6edb1f670193decea3cc8039f21 100644 --- a/ivette/api/plugins/dive/index.ts +++ b/ivette/api/plugins/dive/index.ts @@ -93,11 +93,11 @@ export const jNodeIdSafe: Json.Safe<nodeId> = /** Natural order for `nodeId` */ export const byNodeId: Compare.Order<nodeId> = Compare.number; -/** The callstack context for a node */ -export type callstack = { fun: string, instr: number | string }; +/** A callsite */ +export type callsite = { fun: string, instr: number | string }; -/** Loose decoder for `callstack` */ -export const jCallstack: Json.Loose<callstack> = +/** Loose decoder for `callsite` */ +export const jCallsite: Json.Loose<callsite> = Json.jObject({ fun: Json.jFail(Json.jString,'String expected'), instr: Json.jFail( @@ -105,18 +105,32 @@ export const jCallstack: Json.Loose<callstack> = 'Union expected'), }); -/** Safe decoder for `callstack` */ -export const jCallstackSafe: Json.Safe<callstack> = - Json.jFail(jCallstack,'Callstack expected'); +/** Safe decoder for `callsite` */ +export const jCallsiteSafe: Json.Safe<callsite> = + Json.jFail(jCallsite,'Callsite expected'); -/** Natural order for `callstack` */ -export const byCallstack: Compare.Order<callstack> = +/** Natural order for `callsite` */ +export const byCallsite: Compare.Order<callsite> = Compare.byFields <{ fun: string, instr: number | string }>({ fun: Compare.string, instr: Compare.structural, }); +/** The callstack context for a node */ +export type callstack = callsite[]; + +/** Safe decoder for `callstack` */ +export const jCallstackSafe: Json.Safe<callstack> = + Json.jArray(jCallsiteSafe); + +/** Loose decoder for `callstack` */ +export const jCallstack: Json.Loose<callstack> = Json.jTry(jCallstackSafe); + +/** Natural order for `callstack` */ +export const byCallstack: Compare.Order<callstack> = + Compare.array(byCallsite); + /** The description of a node locality */ export type nodeLocality = { file: string, callstack?: callstack }; diff --git a/ivette/src/frama-c/dive/Dive.tsx b/ivette/src/frama-c/dive/Dive.tsx index bfc4056e79ac8648ef4e017c4747c4112cdff243..7edc9f8da8bd47f5d6a73541e7663131255b2c24 100644 --- a/ivette/src/frama-c/dive/Dive.tsx +++ b/ivette/src/frama-c/dive/Dive.tsx @@ -36,7 +36,7 @@ interface CytoscapeExtended extends Cytoscape.Core { cxtmenu(options: any): void; } -function callstackToString(callstack: API.callstack[]): string { +function callstackToString(callstack: API.callstack): string { return callstack.map((cs) => `${cs.fun}:${cs.instr}`).join('/'); } @@ -139,8 +139,7 @@ class Dive { return this.cy.add({ data: { id, label: fileName }, classes: 'file' }); } - referenceCallstack(callstack: API.callstack[]): Cytoscape.NodeSingular | null - { + referenceCallstack(callstack: API.callstack): Cytoscape.NodeSingular | null { const name = callstackToString(callstack); const elt = callstack.shift(); diff --git a/src/plugins/dive/server_interface.ml b/src/plugins/dive/server_interface.ml index 71a309b3c1ed02a21ead8bd1594f1444be8d5385..0bd290f0608a3cf8d647480f03386158d5eaf152 100644 --- a/src/plugins/dive/server_interface.ml +++ b/src/plugins/dive/server_interface.ml @@ -151,16 +151,23 @@ struct Data.failure "no node '%d' in the current graph" node_key end -module Callstack = +module Callsite = struct - let name = "callstack" - let descr = Markdown.plain "The callstack context for a node" + let name = "callsite" + let descr = Markdown.plain "A callsite" let jtype = Data.declare ~package ~name ~descr (Jrecord [ "fun", Jstring; "instr", Junion [ Jnumber ; Jstring ]; ]) end +module Callstack = +struct + let name = "callstack" + let descr = Markdown.plain "The callstack context for a node" + let jtype = Data.declare ~package ~name ~descr (Jarray Callsite.jtype) +end + module NodeLocality = struct let name = "nodeLocality"