Skip to content
Snippets Groups Projects
Commit 06a81c1e authored by Loïc Correnson's avatar Loïc Correnson
Browse files

Merge branch 'master' into feature/ivette/fix-markers

# Conflicts:
#	ivette/src/dome/renderer/data/json.ts
parents e3a6f495 584caf2c
No related branches found
No related tags found
No related merge requests found
......@@ -47,13 +47,54 @@ export type jobject = { [key: string]: json };
Stores a string telling what was expected and a json of what have been
given */
class JsonError extends Error {
expected = '';
constructor(expected: string, given: json) {
super(`expected ${expected} but given ${given}`);
export class JsonError extends Error {
given: json;
constructor(given: json) {
super("wrong json data type");
this.name = this.constructor.name;
this.given = given;
}
}
class JsonTypeError extends JsonError {
expected: string;
constructor(expected: string, given: json) {
super(given);
this.expected = expected;
}
toString(): string {
return `expected ${this.expected} but given ${JSON.stringify(this.given)}`;
}
}
class JsonUnionError extends JsonError {
#errors: JsonError[];
constructor(errors: JsonError[], given: json) {
super(given);
this.#errors = errors;
}
get errors(): JsonTypeError[] {
let errorsDeep: JsonTypeError[] = [];
this.#errors.forEach(e => {
if (e instanceof JsonTypeError) {
errorsDeep.push(e);
}
else if (e instanceof JsonUnionError) {
errorsDeep = errorsDeep.concat(e.errors);
}
});
return errorsDeep;
}
toString(): string {
return 'none of the union options are valid.\n' +
this.errors.map((e) => ` - ${e}`).join('\n');
}
}
/**
......@@ -124,10 +165,10 @@ export function identity<A>(v: A): A { return v; }
export const jNull: Decoder<null> = (js: json) => {
if (js === null) {
return null;
}
else {
throw new JsonError("null", js);
}
}
else {
throw new JsonTypeError("null", js);
}
};
/** Identity. */
......@@ -139,7 +180,7 @@ export const jObj: Decoder<jobject> = (js: json) => {
return js;
}
else {
throw new JsonError("object", js);
throw new JsonTypeError("object", js);
}
};
......@@ -149,7 +190,7 @@ export const jNumber: Decoder<number> = (js: json) => {
return js;
}
else {
throw new JsonError("object", js);
throw new JsonTypeError("number", js);
}
};
......@@ -159,7 +200,7 @@ export const jInt: Decoder<number> = (js: json) => {
return js;
}
else {
throw new JsonError("integer", js);
throw new JsonTypeError("integer", js);
}
};
......@@ -174,7 +215,7 @@ export const jBoolean: Decoder<boolean> = (js: json) => {
return js;
}
else {
throw new JsonError("boolean", js);
throw new JsonTypeError("boolean", js);
}
};
......@@ -190,14 +231,14 @@ export const jFalse: Decoder<boolean> = (js: json) => (
/** Primitive JSON string or throws JsonError. */
export const jString: Decoder<string> = (js: json) => {
if (typeof js === 'string') {
return js;
}
else {
throw new JsonError("string", js);
}
};
if (typeof js === 'string') {
return js;
}
else {
throw new JsonTypeError("string", js);
}
};
/** JSON constant.
Capture the tag or throw JsonError.
......@@ -210,7 +251,7 @@ export function jTag<A>(tg: A): Decoder<A> {
return tg;
}
else {
throw new JsonError(`"${tg}"`, js);
throw new JsonTypeError(`"${tg}"`, js);
}
};
}
......@@ -226,7 +267,7 @@ export function jEnum<A>(d: { [tag: string]: A }): Decoder<A> {
}
else {
const tags = Object.keys(d).map((tg) => `"${tg}"`);
throw new JsonError(tags.join(' | '), js);
throw new JsonTypeError(tags.join(' | '), js);
}
};
}
......@@ -245,7 +286,7 @@ export function jTags<A extends string | number>(...values: A[]): Decoder<A> {
}
else {
const tags = values.map((tg) => typeof tg === 'string' ? `"${tg}"` : tg);
throw new JsonError(tags.join(' | '), js);
throw new JsonTypeError(tags.join(' | '), js);
}
};
}
......@@ -293,7 +334,7 @@ export function jMap<A>(fn: Decoder<A>): Decoder<Map<string, A>> {
return m;
}
else {
throw new JsonError('object', js);
throw new JsonTypeError('object', js);
}
};
}
......@@ -324,7 +365,7 @@ export function jArray<A>(fn: Decoder<A>): Decoder<A[]> {
return js.map(fn);
}
else {
throw new JsonError('array', js);
throw new JsonTypeError('array', js);
}
};
}
......@@ -354,7 +395,7 @@ export function jList<A>(fn: Decoder<A>): Decoder<A[]> {
return buffer;
}
else {
throw new JsonError('array', js);
throw new JsonTypeError('array', js);
}
};
}
......@@ -385,7 +426,7 @@ export function jPair<A, B>(
return [fa(js[0]) as A, fb(js[1]) as B];
}
else {
throw new JsonError('[A, B]', js);
throw new JsonTypeError('[A, B]', js);
}
};
}
......@@ -401,7 +442,7 @@ export function jTriple<A, B, C>(
return [fa(js[0]), fb(js[1]), fc(js[2])];
}
else {
throw new JsonError('[A, B, C]', js);
throw new JsonTypeError('[A, B, C]', js);
}
};
}
......@@ -418,7 +459,7 @@ export function jTuple4<A, B, C, D>(
return [fa(js[0]), fb(js[1]), fc(js[2]), fd(js[3])];
}
else {
throw new JsonError('[A, B, C, D]', js);
throw new JsonTypeError('[A, B, C, D]', js);
}
};
}
......@@ -436,7 +477,7 @@ export function jTuple5<A, B, C, D, E>(
return [fa(js[0]), fb(js[1]), fc(js[2]), fd(js[3]), fe(js[4])];
}
else {
throw new JsonError('[A, B, C, D, E]', js);
throw new JsonTypeError('[A, B, C, D, E]', js);
}
};
}
......@@ -463,7 +504,7 @@ export function jObject<A extends object>(decoders: Props<A>): Decoder<A> {
return buffer as A; // All fields should be present
}
else {
throw new JsonError('object', js);
throw new JsonTypeError('object', js);
}
};
}
......@@ -473,14 +514,14 @@ export function jObject<A extends object>(decoders: Props<A>): Decoder<A> {
*/
export function jUnion<A>(...cases: Decoder<A>[]): Decoder<A> {
return (js: json) => {
const errors = [];
const errors: JsonError[] = [];
for (const fv of cases) {
try {
return fv(js);
}
catch (err) {
if (err instanceof JsonError) {
errors.push(err.expected);
errors.push(err);
continue;
}
else {
......@@ -488,7 +529,7 @@ export function jUnion<A>(...cases: Decoder<A>[]): Decoder<A> {
}
}
}
throw new JsonError(errors.join(' or '), js);
throw new JsonUnionError(errors, js);
};
}
......@@ -548,7 +589,7 @@ export function jKey<K>(kd: K): Decoder<key<K>> {
return forge(kd, js);
}
else {
throw new JsonError(`key<${kd}>`, js);
throw new JsonTypeError(`key<${kd}>`, js);
}
};
}
......@@ -560,7 +601,7 @@ export function jIndex<K>(kd: K): Decoder<index<K>> {
return forge(kd, js);
}
else {
throw new JsonError(`index<${kd}>`, js);
throw new JsonTypeError(`index<${kd}>`, js);
}
};
}
......
......@@ -764,7 +764,13 @@ export function send<In, Out>(
try {
resolve(request.output(js));
} catch (err) {
reject(`Invalid ${request.name} response (${err})`);
const message = `Invalid ${request.name} response: ${err}`;
if (err instanceof Json.JsonError) {
reject(`${message}\nThe whole response was:\n${Json.stringify(js)}`);
}
else {
reject(message);
}
}
};
pending.set(rid, { resolve: unwrap, reject });
......
......@@ -321,15 +321,20 @@ let is_relevant ip =
not (Ast_info.is_frama_c_builtin (Kernel_function.get_name kf)
|| Cil_builtins.is_unused_builtin (Kernel_function.get_vi kf))
let iter f = Property_status.iter (fun ip -> if is_relevant ip then f ip)
let iter f =
Property_status.iter (fun ip -> if is_relevant ip then f ip)
let add_update_hook f =
Property_status.register_property_add_hook
(fun ip -> if is_relevant ip then f ip);
(* Must reload the entire table when status changed: property dependencies
are not taken into account when status are updated. *)
let add_reload_hook (f : unit -> unit) : unit =
Property_status.register_status_update_hook
(fun _emitter ip _status -> if is_relevant ip then f ip)
(fun _emitter _ip _status -> f())
let add_update_hook (f : Property.t -> unit) : unit =
Property_status.register_property_add_hook
(fun ip -> if is_relevant ip then f ip)
let add_remove_hook f =
let add_remove_hook (f : Property.t -> unit) : unit =
Property_status.register_property_remove_hook
(fun ip -> if is_relevant ip then f ip)
......@@ -341,8 +346,9 @@ let array =
~key:(fun ip -> Kernel_ast.Marker.tag (PIP ip))
~keyType:Kernel_ast.Marker.jtype
~iter
~add_update_hook
~add_reload_hook
~add_remove_hook
~add_update_hook
model
let reload () = States.reload array
......
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