From 88c3379af03f7cb9ec6dc960399eea9461c0c1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 29 Jun 2020 15:38:11 +0200 Subject: [PATCH] [frama-c] upgrade API --- ivette/api/dive/index.ts | 7 +++--- ivette/api/kernel/ast/index.ts | 22 +++++++++++------- ivette/api/kernel/properties/index.ts | 11 +++++---- ivette/api/kernel/services/index.ts | 3 ++- ivette/api/server_tsc.ml | 22 ++++++++++-------- ivette/src/renderer/ASTview.tsx | 2 +- ivette/src/renderer/Globals.tsx | 20 ++--------------- ivette/src/renderer/Properties.tsx | 32 +++++++++++++-------------- 8 files changed, 59 insertions(+), 60 deletions(-) diff --git a/ivette/api/dive/index.ts b/ivette/api/dive/index.ts index 7433dc5f951..a6bfaf5c218 100644 --- a/ivette/api/dive/index.ts +++ b/ivette/api/dive/index.ts @@ -68,7 +68,9 @@ export const addVar: Server.ExecRequest<variableName,Json.json> = { }; /** Add all alarms of the given function */ -export const addFunctionAlarms: Server.ExecRequest<Json.key<'#fct'>,Json.json +export const addFunctionAlarms: Server.ExecRequest< + Json.key<'#fct'>, + Json.json > = { kind: Server.RqKind.EXEC, name: 'dive.addFunctionAlarms', @@ -77,8 +79,7 @@ export const addFunctionAlarms: Server.ExecRequest<Json.key<'#fct'>,Json.json }; /** Explore the graph starting from an existing vertex */ -export const explore: Server.ExecRequest<Json.index<'#dive-node'>,Json.json - > = { +export const explore: Server.ExecRequest<Json.index<'#dive-node'>,Json.json> = { kind: Server.RqKind.EXEC, name: 'dive.explore', input: Json.jIndex<'#dive-node'>('#dive-node'), diff --git a/ivette/api/kernel/ast/index.ts b/ivette/api/kernel/ast/index.ts index 0709335396e..a7c5a9921cb 100644 --- a/ivette/api/kernel/ast/index.ts +++ b/ivette/api/kernel/ast/index.ts @@ -132,9 +132,11 @@ export const reloadMarkerInfo: Server.GetRequest<null,null> = { }; /** Data fetcher for array [`markerInfo`](#markerinfo) */ -export const fetchMarkerInfo: Server.GetRequest<number, +export const fetchMarkerInfo: Server.GetRequest< + number, { pending: number, updated: markerInfoData[], - removed: Json.key<'#markerInfo'>[], reload: boolean }> = { + removed: Json.key<'#markerInfo'>[], reload: boolean } + > = { kind: Server.RqKind.GET, name: 'kernel.ast.fetchMarkerInfo', input: Json.jNumber, @@ -147,12 +149,13 @@ export const fetchMarkerInfo: Server.GetRequest<number, }; /** Marker informations */ -export const markerInfo: State.Array<'#markerInfo',markerInfoData> = { +export const markerInfo: State.Array<Json.key<'#markerInfo'>,markerInfoData> = { name: 'kernel.ast.markerInfo', - key: 'key', + getkey: ((d:markerInfoData) => d.key), signal: signalMarkerInfo, fetch: fetchMarkerInfo, reload: reloadMarkerInfo, + order: byMarkerInfoData, }; /** Localizable AST markers */ @@ -244,9 +247,11 @@ export const reloadFunctions: Server.GetRequest<null,null> = { }; /** Data fetcher for array [`functions`](#functions) */ -export const fetchFunctions: Server.GetRequest<number, +export const fetchFunctions: Server.GetRequest< + number, { pending: number, updated: functionsData[], - removed: Json.key<'#functions'>[], reload: boolean }> = { + removed: Json.key<'#functions'>[], reload: boolean } + > = { kind: Server.RqKind.GET, name: 'kernel.ast.fetchFunctions', input: Json.jNumber, @@ -259,12 +264,13 @@ export const fetchFunctions: Server.GetRequest<number, }; /** AST Functions */ -export const functions: State.Array<'#functions',functionsData> = { +export const functions: State.Array<Json.key<'#functions'>,functionsData> = { name: 'kernel.ast.functions', - key: 'key', + getkey: ((d:functionsData) => d.key), signal: signalFunctions, fetch: fetchFunctions, reload: reloadFunctions, + order: byFunctionsData, }; /** Get textual information about a marker */ diff --git a/ivette/api/kernel/properties/index.ts b/ivette/api/kernel/properties/index.ts index f04292d0a80..3e336583d5a 100644 --- a/ivette/api/kernel/properties/index.ts +++ b/ivette/api/kernel/properties/index.ts @@ -299,9 +299,11 @@ export const reloadStatus: Server.GetRequest<null,null> = { }; /** Data fetcher for array [`status`](#status) */ -export const fetchStatus: Server.GetRequest<number, +export const fetchStatus: Server.GetRequest< + number, { pending: number, updated: statusData[], removed: Json.key<'#status'>[], - reload: boolean }> = { + reload: boolean } + > = { kind: Server.RqKind.GET, name: 'kernel.properties.fetchStatus', input: Json.jNumber, @@ -314,12 +316,13 @@ export const fetchStatus: Server.GetRequest<number, }; /** Status of Registered Properties */ -export const status: State.Array<'#status',statusData> = { +export const status: State.Array<Json.key<'#status'>,statusData> = { name: 'kernel.properties.status', - key: 'key', + getkey: ((d:statusData) => d.key), signal: signalStatus, fetch: fetchStatus, reload: reloadStatus, + order: byStatusData, }; /* ------------------------------------- */ diff --git a/ivette/api/kernel/services/index.ts b/ivette/api/kernel/services/index.ts index fcfcf35b1fb..7da04e4a0ae 100644 --- a/ivette/api/kernel/services/index.ts +++ b/ivette/api/kernel/services/index.ts @@ -25,7 +25,8 @@ import { jTagSafe } from 'api/kernel/data'; import { tag } from 'api/kernel/data'; /** Frama-C Kernel configuration */ -export const getConfig: Server.GetRequest<null, +export const getConfig: Server.GetRequest< + null, { pluginpath: string[], libdir: string, datadir: string, version: string } > = { kind: Server.RqKind.GET, diff --git a/ivette/api/server_tsc.ml b/ivette/api/server_tsc.ml index cf88117b4e2..3df4c37188e 100644 --- a/ivette/api/server_tsc.ml +++ b/ivette/api/server_tsc.ml @@ -311,7 +311,7 @@ let makeDeclaration fmt names d = let output = typeOfParam rq.rq_output in let makeParam fmt js = makeDecoder ~safe:false ~names fmt js in Format.fprintf fmt - "@[<hov 2>export const %s: Server.%sRequest<@,%a,@,%a@,> = {@]@\n" + "@[<hv 2>export const %s: Server.%sRequest<@,%a,@,%a@,>@] = {@\n" self.name prefix jtype input jtype output ; Format.fprintf fmt " kind: Server.RqKind.%s,@\n" kind ; Format.fprintf fmt " name: '%s',@\n" (Pkg.name_of_ident d.d_ident) ; @@ -321,7 +321,7 @@ let makeDeclaration fmt names d = | D_value js -> Format.fprintf fmt - "@[<hov 2>export const %s: State.Value<@,%a@,> = {@]@\n" + "@[<hv 2>export const %s: State.Value<@,%a@,>@] = {\n" self.name jtype js ; Format.fprintf fmt " name: '%s',@\n" (Pkg.name_of_ident self) ; Format.fprintf fmt " signal: %a,@\n" @@ -332,7 +332,7 @@ let makeDeclaration fmt names d = | D_state js -> Format.fprintf fmt - "@[<hov 2>export const %s: State.State<@,%a@,> = {@]@\n" + "@[<hv 2>export const %s: State.State<@,%a@,>@] = {@\n" self.name jtype js ; Format.fprintf fmt " name: '%s',@\n" (Pkg.name_of_ident self) ; Format.fprintf fmt " signal: %a,@\n" @@ -345,34 +345,38 @@ let makeDeclaration fmt names d = | D_array { arr_key ; arr_kind } -> let data = Pkg.Derived.data self in + let jkey = (Pkg.Jkey arr_kind) in + let jrow = (Pkg.Jdata data) in Format.fprintf fmt - "@[<hov 2>export const %s: State.Array<@,'#%s',@,%a@,> = {@]@\n" - self.name arr_kind (jcall names) data ; + "@[<hv 2>export const %s: State.Array<@,%a,@,%a@,>@] = {@\n" + self.name jtype jkey jtype jrow ; Format.fprintf fmt " name: '%s',@\n" (Pkg.name_of_ident self) ; - Format.fprintf fmt " key: '%s',@\n" arr_key ; + Format.fprintf fmt " getkey: ((d:%a) => d.%s),@\n" jtype jrow arr_key ; Format.fprintf fmt " signal: %a,@\n" (jcall names) (Pkg.Derived.signal self) ; Format.fprintf fmt " fetch: %a,@\n" (jcall names) (Pkg.Derived.fetch self) ; Format.fprintf fmt " reload: %a,@\n" (jcall names) (Pkg.Derived.reload self) ; + Format.fprintf fmt " order: %a,@\n" + (jcall names) (Pkg.Derived.order data) ; Format.fprintf fmt "};@\n" | D_safe(id,js) -> Format.fprintf fmt - "@[<hov 2>export const %s: Json.Safe<@,%a@,> =@ %a;@]\n" + "@[<hov 2>@[<hv 0>export const %s: Json.Safe<@,%a@,>@] =@ %a;@]\n" self.name (jcall names) id (makeRecursive (makeRootDecoder ~safe:true ~self:id ~names)) js | D_loose(id,js) -> Format.fprintf fmt - "@[<hov 2>export const %s: Json.Loose<@,%a@,> =@ %a;@]\n" + "@[<hov 2>@[<hv 0>export const %s: Json.Loose<@,%a@,>@] =@ %a;@]\n" self.name (jcall names) id (makeRecursive (makeRootDecoder ~safe:false ~self:id ~names)) js | D_order(id,js) -> Format.fprintf fmt - "@[<hov 2>export const %s: Compare.Order<@,%a@,> =@ %a;@]\n" + "@[<hov 2>@[<hv 0>export const %s: Compare.Order<@,%a@,>@] =@ %a;@]\n" self.name (jcall names) id (makeRecursive2 (makeOrder ~self:id ~names)) js diff --git a/ivette/src/renderer/ASTview.tsx b/ivette/src/renderer/ASTview.tsx index 5ec7d4272ee..5fc898ca878 100644 --- a/ivette/src/renderer/ASTview.tsx +++ b/ivette/src/renderer/ASTview.tsx @@ -78,7 +78,7 @@ const ASTview = () => { const [theme, setTheme] = Dome.useGlobalSetting('ASTview.theme', 'default'); const [fontSize, setFontSize] = Dome.useGlobalSetting('ASTview.fontSize', 12); const [wrapText, setWrapText] = Dome.useSwitch('ASTview.wrapText', false); - const markers = States.useSyncArray(markerInfo); + const markers = States.useSyncModel(markerInfo); const theFunction = selection?.current?.function; const theMarker = selection?.current?.marker; diff --git a/ivette/src/renderer/Globals.tsx b/ivette/src/renderer/Globals.tsx index 94a501716c0..5d4e1cd82df 100644 --- a/ivette/src/renderer/Globals.tsx +++ b/ivette/src/renderer/Globals.tsx @@ -3,10 +3,8 @@ // -------------------------------------------------------------------------- import React from 'react'; -import * as Dome from 'dome'; import { Section, Item } from 'dome/frame/sidebars'; import * as States from 'frama-c/states'; -import { alpha } from 'dome/data/compare'; import { functions, functionsData } from 'api/kernel/ast'; // -------------------------------------------------------------------------- @@ -17,23 +15,9 @@ export default () => { // Hooks const [selection, updateSelection] = States.useSelection(); - const model = States.useSyncArray(functions); - const forceUpdate = Dome.useForceUpdate() as (() => void); - React.useEffect(() => { - model.setNaturalOrder((f1, f2) => alpha(f1.name, f2.name)); - const client = model.link(); - client.onReload(forceUpdate); - client.onUpdate(forceUpdate); - return client.unlink; - }, [model, forceUpdate]); - - // Functions - const n = model.getRowCount(); - const fcts: functionsData[] = []; - for (let i = 0; i < n; i++) { - fcts.push(model.getRowAt(i)); - } + const fcts = States.useSyncArray(functions); + // Items const current: undefined | string = selection?.current?.function; const makeFctItem = (fct: functionsData) => { const kf = fct.name; diff --git a/ivette/src/renderer/Properties.tsx b/ivette/src/renderer/Properties.tsx index 6e44c4a4d55..b3b63b9c570 100644 --- a/ivette/src/renderer/Properties.tsx +++ b/ivette/src/renderer/Properties.tsx @@ -3,12 +3,14 @@ // -------------------------------------------------------------------------- import _ from 'lodash'; -import React from 'react'; +import React, { useEffect } from 'react'; import * as Dome from 'dome'; +import { key } from 'dome/data/json'; import * as States from 'frama-c/states'; import * as Compare from 'dome/data/compare'; import { Label, Code } from 'dome/controls/labels'; import { IconButton } from 'dome/controls/buttons'; +import * as Models from 'dome/table/models'; import * as Arrays from 'dome/table/arrays'; import { Table, Column, ColumnProps, Renderer } from 'dome/table/views'; import { TitleBar, Component } from 'frama-c/LabViews'; @@ -238,13 +240,13 @@ const byColumn: Arrays.ByColumns<Property> = { file: Compare.byFields<Property>({ source: byFile }), }; -class PropertyModel extends Arrays.ArrayModel<Property> { +class PropertyModel extends Arrays.CompactModel<key<'#status'>, Property> { private filterFun?: string; private filterProp = _.cloneDeep(defaultFilter); constructor() { - super('key'); + super((p: Property) => p.key); this.setOrderingByFields(byProperty); this.setColumnOrder(byColumn); this.setFilter(this.filterItem.bind(this)); @@ -410,19 +412,13 @@ const PropertyColumns = () => { }; function FilterRatio({ model }: { model: PropertyModel }) { - const forceUpdate = Dome.useForceUpdate() as (() => void); - React.useEffect(() => { - const client = model.link(); - client.onReload(forceUpdate); - return client.unlink; - }); - const filtered = model.getRowCount(); - const total = model.getTotalRowCount(); + Models.useModel(model); + const [filtered, total] = [model.getRowCount(), model.getTotalRowCount()]; return ( <Label className="component-info" title="Displayed Properties / Total" - display={filtered !== total} + display={filtered !== total || true} > {filtered} / {total} </Label> @@ -436,8 +432,12 @@ function FilterRatio({ model }: { model: PropertyModel }) { const RenderTable = () => { // Hooks const model = React.useMemo(() => new PropertyModel(), []); - - States.useSyncArray<'#status', Property>(Properties.status, model); + const data = States.useSyncArray(Properties.status); + useEffect(() => { + model.removeAllData(); + model.updateData(data); + model.reload(); + }, [model, data]); const [selection, updateSelection] = States.useSelection(); @@ -454,8 +454,8 @@ const RenderTable = () => { // Callbacks const onPropertySelection = React.useCallback( - ({ key, function: fct }: Property) => { - const location = { function: fct, marker: key }; + ({ key: propKey, function: fct }: Property) => { + const location = { function: fct, marker: propKey }; updateSelection({ location }); }, [updateSelection], ); -- GitLab