Как читать / записывать местоположение из / в json файл с помощью Rascal - PullRequest
1 голос
/ 21 января 2020

Мы используем функцию lang::json::IO::writeJSON() для сериализации некоторых данных в файл JSON.

Это прекрасно работало, пока мы не попытались сохранить местоположение метода. Местоположение содержит начальную строку и столбец между символами < и >, что, по-видимому, не является проблемой для записи в файл JSON (он записывается в виде строки, не пытаясь ничего проанализировать).

Проблема начинается, когда вы хотите использовать lang::json::IO::readJSON с местоположением, сохраненным в виде строки. Rascal пытается разобрать строку как объект, и терпит неудачу.

Например:

rascal>map[str, loc] metrics = ();
map[str, loc]: ()
rascal>metrics["test"] = a;
map[str, loc]: ("test":|project:///rascal/bla.java|(0,0,<0,0>,<1,0>))
rascal>writeJSON(|file:///tmp/test.json|,metrics);
ok
rascal>metrics = readJSON(#map[str, loc], |file:///tmp/test.json|);
|std:///lang/json/IO.rsc|(925,2980,<30,0>,<58,160>): IO("could not parse URI:$.test")
        at *** somewhere ***(|std:///lang/json/IO.rsc|(925,2980,<30,0>,<58,160>))
        at readJSON(|std:///lang/json/IO.rsc|(3873,30,<58,128>,<58,158>))

Есть ли лучший способ сериализации / десериализации loc экземпляров в файл JSON?

Оцените вашу помощь с этим!

1 Ответ

1 голос
/ 21 января 2020

Решение состоит в том, чтобы записать местоположения в виде JSon объектов, а не строк, например:

writeJSON(|file:///tmp/test.json|,metrics, unpackedLocations=true);

При чтении файла анализатор увидит, что ему нужно преобразовать объект обратно в расположение источника Rascal путем интерпретации имен каждого поля.

rascal>l = |project://x/y/z|(10,10,<1,2>,<3,4>);
loc: |project://x/y/z|(10,10,<1,2>,<3,4>)

rascal>writeJSON(|home:///example.txt|, [l], unpackedLocations=true)
ok

rascal>println(readFile(|home:///example.txt|))
[{"scheme":"project","authority":"x","path":"/y/z","offset":10,"length":10,"begin":[1,2],"end":[3,4]}]

rascal>readJSON(#list[loc], |home:///example.txt|)
list[loc]: [|file:///y/z|(10,10,<1,2>,<3,4>)]

ok
...