From 81e15d00ca2e5ef47e83c370fffe2624b3183b4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr>
Date: Thu, 25 Jun 2020 02:08:21 +0200
Subject: [PATCH] [ivette] fix phantom key

---
 ivette/api/dive/index.ts              |  8 ++++----
 ivette/api/kernel/ast/index.ts        | 28 ++++++++++++++-------------
 ivette/api/kernel/project/index.ts    |  7 ++++---
 ivette/api/kernel/properties/index.ts |  8 ++++----
 ivette/api/server_tsc.ml              |  4 ++--
 src/plugins/server/states.ml          |  8 ++++----
 6 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/ivette/api/dive/index.ts b/ivette/api/dive/index.ts
index cb63f717365..7433dc5f951 100644
--- a/ivette/api/dive/index.ts
+++ b/ivette/api/dive/index.ts
@@ -72,7 +72,7 @@ export const addFunctionAlarms: Server.ExecRequest<Json.key<'#fct'>,Json.json
   > = {
   kind: Server.RqKind.EXEC,
   name:   'dive.addFunctionAlarms',
-  input:  Json.jKey('#fct'),
+  input:  Json.jKey<'#fct'>('#fct'),
   output: Json.jAny,
 };
 
@@ -81,7 +81,7 @@ export const explore: Server.ExecRequest<Json.index<'#dive-node'>,Json.json
   > = {
   kind: Server.RqKind.EXEC,
   name:   'dive.explore',
-  input:  Json.jIndex('#dive-node'),
+  input:  Json.jIndex<'#dive-node'>('#dive-node'),
   output: Json.jAny,
 };
 
@@ -89,7 +89,7 @@ export const explore: Server.ExecRequest<Json.index<'#dive-node'>,Json.json
 export const show: Server.ExecRequest<Json.index<'#dive-node'>,Json.json> = {
   kind: Server.RqKind.EXEC,
   name:   'dive.show',
-  input:  Json.jIndex('#dive-node'),
+  input:  Json.jIndex<'#dive-node'>('#dive-node'),
   output: Json.jAny,
 };
 
@@ -97,7 +97,7 @@ export const show: Server.ExecRequest<Json.index<'#dive-node'>,Json.json> = {
 export const hide: Server.ExecRequest<Json.index<'#dive-node'>,Json.json> = {
   kind: Server.RqKind.EXEC,
   name:   'dive.hide',
-  input:  Json.jIndex('#dive-node'),
+  input:  Json.jIndex<'#dive-node'>('#dive-node'),
   output: Json.jAny,
 };
 
diff --git a/ivette/api/kernel/ast/index.ts b/ivette/api/kernel/ast/index.ts
index 7d601286791..0709335396e 100644
--- a/ivette/api/kernel/ast/index.ts
+++ b/ivette/api/kernel/ast/index.ts
@@ -96,7 +96,8 @@ export interface markerInfoData {
 /** Loose decoder for `markerInfoData` */
 export const jMarkerInfoData: Json.Loose<markerInfoData> =
   Json.jObject({
-    key: Json.jFail(Json.jKey('#markerInfo'),'#markerInfo expected'),
+    key: Json.jFail(Json.jKey<'#markerInfo'>('#markerInfo'),
+           '#markerInfo expected'),
     kind: jMarkerKindSafe,
     name: Json.jFail(Json.jString,'String expected'),
     descr: Json.jFail(Json.jString,'String expected'),
@@ -140,7 +141,7 @@ export const fetchMarkerInfo: Server.GetRequest<number,
   output: Json.jObject({
             pending: Json.jFail(Json.jNumber,'Number expected'),
             updated: Json.jList(jMarkerInfoData),
-            removed: Json.jList(Json.jKey('#markerInfo')),
+            removed: Json.jList(Json.jKey<'#markerInfo'>('#markerInfo')),
             reload: Json.jFail(Json.jBoolean,'Boolean expected'),
           }),
 };
@@ -165,13 +166,13 @@ export const jMarker: Json.Loose<marker> =
   Json.jUnion<Json.key<'#stmt'> | Json.key<'#decl'> | Json.key<'#lval'> |
               Json.key<'#expr'> | Json.key<'#term'> | Json.key<'#global'> |
               Json.key<'#property'>>(
-    Json.jKey('#stmt'),
-    Json.jKey('#decl'),
-    Json.jKey('#lval'),
-    Json.jKey('#expr'),
-    Json.jKey('#term'),
-    Json.jKey('#global'),
-    Json.jKey('#property'),
+    Json.jKey<'#stmt'>('#stmt'),
+    Json.jKey<'#decl'>('#decl'),
+    Json.jKey<'#lval'>('#lval'),
+    Json.jKey<'#expr'>('#expr'),
+    Json.jKey<'#term'>('#term'),
+    Json.jKey<'#global'>('#global'),
+    Json.jKey<'#property'>('#property'),
   );
 
 /** Safe decoder for `marker` */
@@ -186,14 +187,14 @@ export const getFunctions: Server.GetRequest<null,Json.key<'#fct'>[]> = {
   kind: Server.RqKind.GET,
   name:   'kernel.ast.getFunctions',
   input:  Json.jNull,
-  output: Json.jList(Json.jKey('#fct')),
+  output: Json.jList(Json.jKey<'#fct'>('#fct')),
 };
 
 /** Print the AST of a function */
 export const printFunction: Server.GetRequest<Json.key<'#fct'>,text> = {
   kind: Server.RqKind.GET,
   name:   'kernel.ast.printFunction',
-  input:  Json.jKey('#fct'),
+  input:  Json.jKey<'#fct'>('#fct'),
   output: jText,
 };
 
@@ -210,7 +211,8 @@ export interface functionsData {
 /** Loose decoder for `functionsData` */
 export const jFunctionsData: Json.Loose<functionsData> =
   Json.jObject({
-    key: Json.jFail(Json.jKey('#functions'),'#functions expected'),
+    key: Json.jFail(Json.jKey<'#functions'>('#functions'),
+           '#functions expected'),
     name: Json.jFail(Json.jString,'String expected'),
     signature: Json.jFail(Json.jString,'String expected'),
   });
@@ -251,7 +253,7 @@ export const fetchFunctions: Server.GetRequest<number,
   output: Json.jObject({
             pending: Json.jFail(Json.jNumber,'Number expected'),
             updated: Json.jList(jFunctionsData),
-            removed: Json.jList(Json.jKey('#functions')),
+            removed: Json.jList(Json.jKey<'#functions'>('#functions')),
             reload: Json.jFail(Json.jBoolean,'Boolean expected'),
           }),
 };
diff --git a/ivette/api/kernel/project/index.ts b/ivette/api/kernel/project/index.ts
index 456217329fa..ec7ea0fb8f1 100644
--- a/ivette/api/kernel/project/index.ts
+++ b/ivette/api/kernel/project/index.ts
@@ -23,7 +23,7 @@ export type projectInfo =
 /** Loose decoder for `projectInfo` */
 export const jProjectInfo: Json.Loose<projectInfo> =
   Json.jObject({
-    id: Json.jFail(Json.jKey('#project'),'#project expected'),
+    id: Json.jFail(Json.jKey<'#project'>('#project'),'#project expected'),
     name: Json.jFail(Json.jString,'String expected'),
     current: Json.jFail(Json.jBoolean,'Boolean expected'),
   });
@@ -48,7 +48,8 @@ export type projectRequest =
 /** Loose decoder for `projectRequest` */
 export const jProjectRequest: Json.Loose<projectRequest> =
   Json.jObject({
-    project: Json.jFail(Json.jKey('#project'),'#project expected'),
+    project: Json.jFail(Json.jKey<'#project'>('#project'),
+               '#project expected'),
     request: Json.jFail(Json.jString,'String expected'),
     data: Json.jAny,
   });
@@ -78,7 +79,7 @@ export const getCurrent: Server.GetRequest<null,projectInfo> = {
 export const setCurrent: Server.SetRequest<Json.key<'#project'>,null> = {
   kind: Server.RqKind.SET,
   name:   'kernel.project.setCurrent',
-  input:  Json.jKey('#project'),
+  input:  Json.jKey<'#project'>('#project'),
   output: Json.jNull,
 };
 
diff --git a/ivette/api/kernel/properties/index.ts b/ivette/api/kernel/properties/index.ts
index bfe9af2c2bb..f04292d0a80 100644
--- a/ivette/api/kernel/properties/index.ts
+++ b/ivette/api/kernel/properties/index.ts
@@ -248,13 +248,13 @@ export interface statusData {
 /** Loose decoder for `statusData` */
 export const jStatusData: Json.Loose<statusData> =
   Json.jObject({
-    key: Json.jFail(Json.jKey('#status'),'#status expected'),
+    key: Json.jFail(Json.jKey<'#status'>('#status'),'#status expected'),
     descr: Json.jFail(Json.jString,'String expected'),
     kind: jPropKindSafe,
     names: Json.jList(Json.jString),
     status: jPropStatusSafe,
-    function: Json.jKey('#fct'),
-    kinstr: Json.jKey('#stmt'),
+    function: Json.jKey<'#fct'>('#fct'),
+    kinstr: Json.jKey<'#stmt'>('#stmt'),
     source: jSourceSafe,
     alarm: Json.jString,
     alarm_descr: Json.jString,
@@ -308,7 +308,7 @@ export const fetchStatus: Server.GetRequest<number,
   output: Json.jObject({
             pending: Json.jFail(Json.jNumber,'Number expected'),
             updated: Json.jList(jStatusData),
-            removed: Json.jList(Json.jKey('#status')),
+            removed: Json.jList(Json.jKey<'#status'>('#status')),
             reload: Json.jFail(Json.jBoolean,'Boolean expected'),
           }),
 };
diff --git a/ivette/api/server_tsc.ml b/ivette/api/server_tsc.ml
index 3388bcd2311..cf88117b4e2 100644
--- a/ivette/api/server_tsc.ml
+++ b/ivette/api/server_tsc.ml
@@ -102,8 +102,8 @@ let makeJtype ?self ~names =
 (* -------------------------------------------------------------------------- *)
 
 let jprim fmt name = Format.fprintf fmt "Json.%s" name
-let jkey fmt kd = Format.fprintf fmt "Json.jKey('#%s')" kd
-let jindex fmt kd = Format.fprintf fmt "Json.jIndex('#%s')" kd
+let jkey fmt kd = Format.fprintf fmt "Json.jKey<'#%s'>('#%s')" kd kd
+let jindex fmt kd = Format.fprintf fmt "Json.jIndex<'#%s'>('#%s')" kd kd
 
 let jcall names fmt id =
   try Format.pp_print_string fmt (Pkg.IdMap.find id names)
diff --git a/src/plugins/server/states.ml b/src/plugins/server/states.ml
index 9a26d581c2c..5b172c2d4ef 100644
--- a/src/plugins/server/states.ml
+++ b/src/plugins/server/states.ml
@@ -101,8 +101,6 @@ let model () = ref []
 let column (type a b) ~name ~descr
     ~(data: b Request.output) ~(get : a -> b) (model : a model) =
   let module D = (val data) in
-  if name = "key" || name = "index" then
-    raise (Invalid_argument "Server.States.column: invalid name") ;
   if List.exists (fun (fd,_) -> fd.Package.fd_name = name) !model then
     raise (Invalid_argument "Server.States.column: duplicate name") ;
   let fd = Package.{
@@ -273,8 +271,10 @@ let register_array ~package ~name ~descr ~key
   let open Markdown in
   let href = link ~name () in
   let columns = List.rev !model in
+  if List.exists (fun (fd,_) -> fd.Package.fd_name = keyName) columns then
+    raise (Invalid_argument "States.array: key name overrides column name") ;
   let fields = Package.{
-      fd_name = "key" ;
+      fd_name = keyName ;
       fd_type = Jkey keyKind ;
       fd_descr = plain "Entry identifier." ;
     } :: List.map fst columns in
@@ -298,7 +298,7 @@ let register_array ~package ~name ~descr ~key
   let signature = Request.signature ~input:(module Jint) () in
   let module Jkeys = Jlist(struct
       include Jstring
-      let jtype = Package.Jkey name
+      let jtype = Package.Jkey keyKind
     end) in
   let module Jrows = Jlist (struct
       include Jany
-- 
GitLab