Skip to content
Snippets Groups Projects
Commit d5b75e2a authored by David Bühler's avatar David Bühler
Browse files

[server] Simplifies the implementation of request kernel.ast.info.

The request returns the text to be displayed about the selected marker, instead
of structured information to be parsed by the client.
parent 1d41eb45
No related branches found
No related tags found
No related merge requests found
...@@ -11,68 +11,23 @@ import { Text } from 'dome/text/editors'; ...@@ -11,68 +11,23 @@ import { Text } from 'dome/text/editors';
import { Component } from 'frama-c/LabViews'; import { Component } from 'frama-c/LabViews';
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// --- Parsing information from the server // --- Information Panel
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
function addMarker(buffer: RichTextBuffer, fct: string) { const printInfo = (buffer: RichTextBuffer, text: string) => {
buffer.openTextMarker({ id: fct, css: 'color: blue' }); if (Array.isArray(text)) {
buffer.append(fct); const tag = text.shift();
buffer.closeTextMarker(); if (tag !== '') {
} buffer.openTextMarker({ id: tag, css: 'color: blue' });
}
function parseVarinfo(buffer: RichTextBuffer, data: any) { text.forEach((txt) => printInfo(buffer, txt));
buffer.append(`Variable ${data.name} has type '${data.type.name}'.`); if (tag !== '') {
buffer.flushline(); buffer.closeTextMarker();
if (data.global) { }
buffer.append('It is a global variable.'); } else if (typeof (text) === 'string') {
} else { buffer.append(text);
const kind = data.formal ? 'formal' : 'local';
buffer.append(`It is a ${kind} variable of function `);
addMarker(buffer, data.defining_function);
}
buffer.flushline();
if (data.temp) {
const descr = data.descr ? ` for ${data.descr}` : '';
buffer.append(`This is a temporary variable${descr}.`);
buffer.flushline();
}
const ref = data.referenced ? '' : 'not ';
const taken = data.addrof ? '' : 'not ';
buffer.append(`It is ${ref}referenced and its address is ${taken}taken.`);
}
function parseInfo(buffer: RichTextBuffer, data: any) {
switch (data.kind) {
case 'expression':
buffer.append(`This is a pure C expression of type '${data.type.name}'.`);
break;
case 'function':
addMarker(buffer, data.varinfo.name);
buffer.append(` is a C function of type '${data.type.name}'.`);
break;
case 'variable':
parseVarinfo(buffer, data.varinfo);
break;
case 'lvalue':
buffer.append(`This is an lvalue of type '${data.type.name}'.`);
break;
case 'declaration':
buffer.append('This is the declaration of variable '
+ `${data.varinfo.name}.`);
buffer.flushline(); buffer.append(' '); buffer.flushline();
parseVarinfo(buffer, data.varinfo);
break;
case 'statement':
buffer.append(`This is a statement of function ${data.function}.`);
break;
default:
break;
} }
} };
// --------------------------------------------------------------------------
// --- Information Panel
// --------------------------------------------------------------------------
const ASTinfo = () => { const ASTinfo = () => {
...@@ -84,7 +39,7 @@ const ASTinfo = () => { ...@@ -84,7 +39,7 @@ const ASTinfo = () => {
React.useEffect(() => { React.useEffect(() => {
buffer.clear(); buffer.clear();
if (data) { if (data) {
parseInfo(buffer, data); printInfo(buffer, data);
} }
}, [buffer, data]); }, [buffer, data]);
......
...@@ -226,23 +226,6 @@ module Kf = Data.Collection ...@@ -226,23 +226,6 @@ module Kf = Data.Collection
with Not_found -> Data.failure "Undefined function '%s'" key with Not_found -> Data.failure "Undefined function '%s'" key
end) end)
module TypeId =
Data.Index (Cil_datatype.Typ.Map)
(struct
let page = page
let name = "type"
let descr = Md.plain "C Type"
end)
module VarId =
Data.Identified (Cil_datatype.Varinfo_Id)
(struct
let page = page
let name = "varinfo"
let descr = Md.plain "Varinfo"
end)
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
(* --- Functions --- *) (* --- Functions --- *)
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
...@@ -267,133 +250,72 @@ let () = Request.register ~page ...@@ -267,133 +250,72 @@ let () = Request.register ~page
(* --- Information --- *) (* --- Information --- *)
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
module TypeInfo = struct module Info = struct
type record open Printer_tag
let record : record Record.signature =
Record.signature ~page
~name:"type" ~descr:(Md.plain "Information about a C type") ()
let id = Record.field record ~name:"id"
~descr:(Md.plain "Type id") (module Jint)
let name = Record.field record ~name:"name"
~descr:(Md.plain "Type name") (module Jstring)
let size = Record.field record ~name:"size"
~descr:(Md.plain "Bit size") (module Jint.Joption)
module R = (val (Record.publish record) : Record.S with type r = record)
type t = typ
let syntax = R.syntax
let getSize typ =
try Some (Cil.bitsSizeOf typ)
with Cil.SizeOfError _ -> None
let to_json typ =
R.default |>
R.set id (TypeId.get typ) |>
R.set name (Format.asprintf "%a" Printer.pp_typ typ) |>
R.set size (getSize typ) |>
R.to_json
let of_json json =
let r = R.of_json json in
try TypeId.find (R.get id r)
with Not_found -> Data.failure "Unknown type"
end
module VarInfo = struct let print_function fmt name =
type record let stag = Transitioning.Format.stag_of_string name in
Transitioning.Format.pp_open_stag fmt stag;
let record : record Record.signature = Format.pp_print_string fmt name;
Record.signature ~page Transitioning.Format.pp_close_stag fmt ()
~name:"varinfo" ~descr:(Md.plain "Information about a variable") ()
let print_kf fmt kf = print_function fmt (Kernel_function.get_name kf)
let id = Record.field record ~name:"id"
~descr:(Md.plain "Variable id") (module Jint) let print_varinfo fmt vi =
let name = Record.field record ~name:"name" Format.fprintf fmt "Variable %s has type %a.@."
~descr:(Md.plain "Variable name") (module Jstring) vi.vname Printer.pp_typ vi.vtype;
let typ = Record.field record ~name:"type" let kf = Kernel_function.find_defining_kf vi in
~descr:(Md.plain "Variable type") (module TypeInfo) let pp_kf fmt kf = Format.fprintf fmt " of function %a" print_kf kf in
let fct = Record.field record ~name:"function" Format.fprintf fmt "It is a %s variable%a.@."
~descr:(Md.plain "Is the variable a function?") (module Jbool) (if vi.vglob then "global" else if vi.vformal then "formal" else "local")
let global = Record.field record ~name:"global" (Transitioning.Format.pp_print_option pp_kf) kf;
~descr:(Md.plain "Is the variable global?") (module Jbool) if vi.vtemp then
let formal = Record.field record ~name:"formal" Format.fprintf fmt "This is a temporary variable%s.@."
~descr:(Md.plain "Is the variable formal?") (module Jbool) (match vi.vdescr with None -> "" | Some descr -> descr);
let kf = Record.option record ~name:"defining_function" Format.fprintf fmt "It is %sreferenced and its address is %staken.@."
~descr:(Md.plain "Function defining the variable") (module Kf) (if vi.vreferenced then "" else "not ")
let addrof = Record.field record ~name:"addrof" (if vi.vaddrof then "" else "not ")
~descr:(Md.plain "Is the variable address taken?") (module Jbool)
let referenced = Record.field record ~name:"referenced" let print_lvalue fmt _loc = function
~descr:(Md.plain "Is the variable referenced?") (module Jbool) | Var vi, NoOffset ->
let temp = Record.field record ~name:"temp" if Cil.isFunctionType vi.vtype
~descr:(Md.plain "Is the variable temporary?") (module Jbool) then
let descr = Record.option record ~name:"descr" Format.fprintf fmt "%a is a C function of type %a.@."
~descr:(Md.plain "Description of temporary variable") (module Jstring) print_function vi.vname Printer.pp_typ vi.vtype
else print_varinfo fmt vi
module R = (val (Record.publish record) : Record.S with type r = record) | lval ->
Format.fprintf fmt "This is an lvalue of type %a.@."
type t = varinfo Printer.pp_typ (Cil.typeOfLval lval)
let syntax = R.syntax
let print_localizable fmt = function
let to_json vi = | PExp (_, _, e) ->
R.default |> Format.fprintf fmt "This is a pure C expression of type %a.@."
R.set name vi.vname |> Printer.pp_typ (Cil.typeOf e)
R.set typ vi.vtype |> | PLval (_, _, lval) as loc -> print_lvalue fmt loc lval
R.set fct (Cil.isFunctionType vi.vtype) |> | PVDecl (_, _, vi) ->
R.set global vi.vglob |> Format.fprintf fmt "This is the declaration of variable %a.@.@."
R.set formal vi.vformal |> Printer.pp_varinfo vi;
R.set kf (Kernel_function.find_defining_kf vi) |> print_varinfo fmt vi
R.set addrof vi.vaddrof |> | PStmt (kf, _) | PStmtStart (kf, _) ->
R.set referenced vi.vreferenced |> Format.fprintf fmt "This is a statement of function %a@." print_kf kf
R.set temp vi.vtemp |> | _ -> ()
R.set descr vi.vdescr |>
R.to_json let get_marker_info marker =
try
let of_json json = let loc = Marker.lookup marker in
let r = R.of_json json in let buffer = Jbuffer.create () in
try VarId.find (R.get id r) print_localizable (Jbuffer.formatter buffer) loc;
with Not_found -> Data.failure "Unknown varinfo" Jbuffer.flush buffer ();
Jbuffer.contents buffer
with Not_found -> Data.failure "not a localizable marker"
end end
module Info = struct
type record
let record : record Record.signature =
Record.signature ~page ~name:"information"
~descr:(Md.plain "Information about an AST marker") ()
let kind = Record.field record ~name:"kind" ~descr:(Md.plain "Kind")
(module MarkerKind)
let typ = Record.option record ~name:"type" ~descr:(Md.plain "Type")
(module TypeInfo)
let kf = Record.option record ~name:"function" ~descr:(Md.plain "Function")
(module Kf)
let varinfo = Record.option record ~name:"varinfo"
~descr:(Md.plain "Varinfo information")
(module VarInfo)
module R = (val (Record.publish record) : Record.S with type r = record)
type t = Printer_tag.localizable
let syntax = R.syntax
let to_json (loc: t) =
R.default |>
R.set kind loc |>
R.set typ (Printer_tag.typ_of_localizable loc) |>
R.set kf (Printer_tag.kf_of_localizable loc) |>
R.set varinfo (Printer_tag.varinfo_of_localizable loc) |>
R.to_json
end
let () = Request.register ~page let () = Request.register ~page
~kind:`GET ~name:"kernel.ast.info" ~kind:`GET ~name:"kernel.ast.info"
~descr:(Md.plain "Get information about a marker") ~descr:(Md.plain "Get information about a marker")
~input:(module Jstring) ~output:(module Info) ~input:(module Jstring) ~output:(module Jtext)
Marker.lookup Info.get_marker_info
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
(* --- Files --- *) (* --- Files --- *)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment