From 9f5da4959fdbab39eeaf994088ca60cb1ff2362e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 6 Jul 2023 14:59:39 +0200 Subject: [PATCH] [ivette] New file Studia.tsx for Studia related functions, used by ASTview. --- ivette/src/frama-c/kernel/ASTview.tsx | 54 +--------------- ivette/src/frama-c/plugins/studia/studia.ts | 70 +++++++++++++++++++++ 2 files changed, 72 insertions(+), 52 deletions(-) create mode 100644 ivette/src/frama-c/plugins/studia/studia.ts diff --git a/ivette/src/frama-c/kernel/ASTview.tsx b/ivette/src/frama-c/kernel/ASTview.tsx index 35a124c9ea3..a053d494156 100644 --- a/ivette/src/frama-c/kernel/ASTview.tsx +++ b/ivette/src/frama-c/kernel/ASTview.tsx @@ -26,17 +26,15 @@ import Lodash from 'lodash'; import * as Dome from 'dome'; import * as Editor from 'dome/text/editor'; import * as Utils from 'dome/data/arrays'; -import * as Server from 'frama-c/server'; import * as States from 'frama-c/states'; -import { key } from 'dome/data/json'; import * as Settings from 'dome/data/settings'; import { IconButton } from 'dome/controls/buttons'; import { Filler, Inset } from 'dome/frame/toolbars'; +import * as Studia from 'frama-c/plugins/studia/studia'; import * as Ast from 'frama-c/kernel/api/ast'; import { text } from 'frama-c/kernel/api/data'; import * as Eva from 'frama-c/plugins/eva/api/general'; import * as Properties from 'frama-c/kernel/api/properties'; -import { getWritesLval, getReadsLval } from 'frama-c/plugins/studia/api/studia'; import { TitleBar } from 'ivette'; import * as Preferences from 'ivette/prefs'; @@ -486,46 +484,6 @@ function createPropertiesGutter(): Editor.Extension { -// ----------------------------------------------------------------------------- -// Studia access -// ----------------------------------------------------------------------------- - -type access = 'Reads' | 'Writes'; - -interface StudiaProps { - marker: string, - attrs: Ast.markerAttributesData, - kind: access, -} - -interface StudiaInfos { - name: string, - title: string, - locations: { fct: key<'#fct'>, marker: Ast.marker }[], - index: number, -} - -async function studia(props: StudiaProps): Promise<StudiaInfos> { - const { marker, attrs, kind } = props; - const request = kind === 'Reads' ? getReadsLval : getWritesLval; - const data = await Server.send(request, marker); - const locations = data.direct.map(([f, m]) => ({ fct: f, marker: m })); - const lval = attrs.name; - if (locations.length > 0) { - const name = `${kind} of ${lval}`; - const acc = (kind === 'Reads') ? 'accessing' : 'modifying'; - const title = - `List of statements ${acc} the memory location pointed by ${lval}.`; - return { name, title, locations, index: 0 }; - } - const name = `No ${kind.toLowerCase()} of ${lval}`; - return { name, title: '', locations: [], index: 0 }; -} - -// ----------------------------------------------------------------------------- - - - // ----------------------------------------------------------------------------- // Context menu // ----------------------------------------------------------------------------- @@ -583,15 +541,7 @@ function createContextMenuHandler(): Editor.Extension { items.push({ label, onClick }); }); } - const enabled = attrs?.isLval; - const onClick = (kind: access): void => { - if (attrs && node.marker) - studia({ marker: node.marker, attrs, kind }).then(update); - }; - const reads = 'Studia: select reads'; - const writes = 'Studia: select writes'; - items.push({ label: reads, enabled, onClick: () => onClick('Reads') }); - items.push({ label: writes, enabled, onClick: () => onClick('Writes') }); + Studia.buildMenu({ marker: node.marker, attrs, update, menu: items }); const copy = (): void => { const text = view.state.sliceDoc(node.from, node.to); if (text !== '') navigator.clipboard.writeText(text); diff --git a/ivette/src/frama-c/plugins/studia/studia.ts b/ivette/src/frama-c/plugins/studia/studia.ts new file mode 100644 index 00000000000..d84e1fb7e2a --- /dev/null +++ b/ivette/src/frama-c/plugins/studia/studia.ts @@ -0,0 +1,70 @@ +/* ************************************************************************ */ +/* */ +/* This file is part of Frama-C. */ +/* */ +/* Copyright (C) 2007-2023 */ +/* CEA (Commissariat à l'énergie atomique et aux énergies */ +/* alternatives) */ +/* */ +/* you can redistribute it and/or modify it under the terms of the GNU */ +/* Lesser General Public License as published by the Free Software */ +/* Foundation, version 2.1. */ +/* */ +/* It is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* See the GNU Lesser General Public License version 2.1 */ +/* for more details (enclosed in the file licenses/LGPLv2.1). */ +/* */ +/* ************************************************************************ */ + +import * as Dome from 'dome'; +import * as States from 'frama-c/states'; +import * as Server from 'frama-c/server'; +import * as Ast from 'frama-c/kernel/api/ast'; +import { getWritesLval, getReadsLval } from 'frama-c/plugins/studia/api/studia'; + +type access = 'Reads' | 'Writes'; + +async function compute(marker: Ast.marker, label: string, kind: access) + : Promise<States.MultipleSelect> { + const request = kind === 'Reads' ? getReadsLval : getWritesLval; + const data = await Server.send(request, marker); + const locations = data.direct.map(([f, m]) => ({ fct: f, marker: m })); + if (locations.length > 0) { + const name = `${kind} of ${label}`; + const acc = (kind === 'Reads') ? 'accessing' : 'modifying'; + const title = + `List of statements ${acc} the memory location pointed by ${label}.`; + return { name, title, locations, index: 0 }; + } + const name = `No ${kind.toLowerCase()} of ${label}`; + return { name, title: '', locations: [], index: 0 }; +} + +interface MenuProps { + /** The marker on which the menu is applied. */ + marker: Ast.marker, + /** Attributes of the marker. */ + attrs?: Ast.markerAttributesData, + /** Function to update the selection. */ + update: (a: States.SelectionActions) => void, + /** Array to which studia menu entries are added. */ + menu: Dome.PopupMenuItem[], +} + +/** Builds the Studia entries in the contextual menu about a given marker. */ +export function buildMenu(props: MenuProps) : void { + const { update, marker, attrs, menu } = props; + const enabled = attrs?.isLval; + function onClick(kind: access) : void { + if (marker && attrs) + compute(marker, attrs.name, kind).then(update); + } + const reads = 'Studia: select reads'; + const writes = 'Studia: select writes'; + menu.push({ label: reads, enabled, onClick: () => onClick('Reads') }); + menu.push({ label: writes, enabled, onClick: () => onClick('Writes') }); +} -- GitLab