forked from eclipse-langium/langium-website
-
Notifications
You must be signed in to change notification settings - Fork 0
/
preprocess.ts
148 lines (136 loc) · 3.66 KB
/
preprocess.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AstNode, AstNodeLocator } from "langium";
/**
* Represents a serialized version of a reference to an AstNode
*/
export interface Reference<T extends AstNode = AstNode> {
ref?: T;
$ref: string
}
export interface ValueNodeBase {
kind: "object" | "array" | "string" | "boolean" | "number" | "reference" | "undefined";
}
export interface ObjectValueNode extends ValueNodeBase {
kind: "object";
properties: PropertyNode[];
}
export interface UndefinedValueNode extends ValueNodeBase {
kind: "undefined";
}
export interface ReferenceValueNode extends ValueNodeBase {
kind: "reference";
$text: string;
}
export type PrimitiveValueKindMapping = {
string: string;
boolean: boolean;
number: number;
};
export interface PrimitiveValueNode<T extends "number" | "string" | "boolean">
extends ValueNodeBase {
kind: T;
value: PrimitiveValueKindMapping[T];
}
export interface ArrayValueNode extends ValueNodeBase {
kind: "array";
children: ValueNode[];
}
export type ValueNode =
| ObjectValueNode
| ArrayValueNode
| PrimitiveValueNode<"boolean">
| PrimitiveValueNode<"number">
| PrimitiveValueNode<"string">
| ReferenceValueNode
| UndefinedValueNode;
export interface PropertyNode {
name: string;
type: ValueNode;
}
export type AstValue = AstNode | AstNode[] | string | number | boolean | Reference | undefined;
export function preprocessAstNodeValue(
valueOrValues: AstValue,
locator: AstNodeLocator
): ValueNode {
if (Array.isArray(valueOrValues)) {
return preprocessArrayType(valueOrValues, locator);
} else if (typeof valueOrValues === "object" || typeof valueOrValues === "undefined") {
if(!valueOrValues) {
return {kind: "undefined"};
} else if ("$ref" in valueOrValues) {
return preprocessReferenceNode(valueOrValues, locator);
}
return preprocessAstNodeObject(valueOrValues, locator);
} else if (typeof valueOrValues === "string") {
return {
kind: "string",
value: valueOrValues,
} as ValueNode;
} else if (typeof valueOrValues === "number") {
return {
kind: "number",
value: valueOrValues,
} as ValueNode;
} else {
return {
kind: "boolean",
value: valueOrValues,
};
}
}
export function preprocessAstNodeObject(
node: AstNode,
locator: AstNodeLocator
): ObjectValueNode {
const properties: PropertyNode[] = Object.keys(node)
.filter((n) => !n.startsWith("$"))
.map((n) => {
const valueOrValues = ((node as any)[n]) as AstValue;
return {
name: n,
type: preprocessAstNodeValue(valueOrValues, locator),
} as PropertyNode;
});
return {
kind: "object",
properties: [
{
name: "$type",
type: {
kind: "string",
value: node.$type,
},
},
...properties,
],
};
}
export function preprocessReferenceNode(
node: Reference<AstNode>,
locator: AstNodeLocator
): ReferenceValueNode {
// check to display a valid reference, when present
return node.$ref
? {
kind: "reference",
$text: node.$ref
}
: {
kind: "reference",
$text: "???",
};
}
export function preprocessArrayType(
nodes: AstNode[],
locator: AstNodeLocator
): ArrayValueNode {
const children = nodes.map((n) => preprocessAstNodeValue(n, locator));
return {
kind: "array",
children,
};
}