在 Rascal 中导出到 JSON 时控制 属性 名称

Controlling property names when exporting to JSON in Rascal

我正在使用 lang::json::IO 模块中的 writeJSON 将一些数据写入文件。

示例:

map[str, value] volumeMetrics = ();
map[str path, map[loc location, int lineCount] methods] = ...; // some data
volumeMetrics["files"] = methodLineCountPerFile;

如何在不遍历对象层次结构并手动指定它们的情况下控制结果 JSON 中的属性名称?在这种特殊情况下,我希望 JSON 对象具有以地图中定义的标签命名的属性(例如“路径”、“位置”、“行数”、“方法”)。相反,此数据现在直接写为对象属性。

(部分)示例输出:

  "/src/smallsql/database/ExpressionFunctionUCase.java": [
    [
      {
        "scheme": "java+compilationUnit",
        "authority": "",
        "path": "/src/smallsql/database/ExpressionFunctionUCase.java",
        "offset": 1600,
        "length": 32,
        "begin": [
          47,
          41
        ],
        "end": [
          49,
          2
        ]
      },
      3
    ],
    [
      {
        "scheme": "java+compilationUnit",
        "authority": "",
        "path": "/src/smallsql/database/ExpressionFunctionUCase.java",
        "offset": 1679,
        "length": 80,
        "begin": [
          52,
          41
        ],
        "end": [
          55,
          2
        ]
      },
      4
    ],
    [
      {
        "scheme": "java+compilationUnit",
        "authority": "",
        "path": "/src/smallsql/database/ExpressionFunctionUCase.java",
        "offset": 1810,
        "length": 78,
        "begin": [
          58,
          43
        ],
        "end": [
          61,
          2
        ]
      },
      4
    ],
    [
      {
        "scheme": "java+compilationUnit",
        "authority": "",
        "path": "/src/smallsql/database/ExpressionFunctionUCase.java",
        "offset": 1518,
        "length": 35,
        "begin": [
          42,
          25
        ],
        "end": [
          44,
          2
        ]
      },
      3
    ]
  ],

您可以使用 Rascal 的 data 构造函数来创建嵌套结构,然后可以将其映射到 JSON 结构:

rascal>data Metric = path(int i);
ok
rascal>import lang::json::IO;
Loading module |lib://rascal/lang/json/IO.rsc|
ok
rascal>writeJSON(|home:///test.json|, path(20))
ok
rascal>import IO;
ok
rascal>println(readFile(|home:///test.json|))
{"path":{"i":20}}
ok

因此,您可以为您拥有的每种指标创建一个 Metric 构造函数并使用它,或者您可以使用一个具有不同字段的构造函数,如下所示:

rascal>data Metrics = metrics(int a, int b, int c);
ok
rascal>writeJSON(|home:///test.json|, metrics(1,2,3))
ok
rascal>println(readFile(|home:///test.json|))
{"metrics":{"a":1,"b":2,"c":3}}
ok

这里使用构造函数字段的标签来命名指标。

PS,writeJSON的unpackedLocations关键字参数,有助于减少源位置占用space。