@swagger-api/apidom-ast 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +352 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/MIT.txt +9 -0
- package/NOTICE +57 -0
- package/README.md +98 -0
- package/cjs/Error.cjs +25 -0
- package/cjs/Literal.cjs +22 -0
- package/cjs/Node.cjs +46 -0
- package/cjs/ParseResult.cjs +22 -0
- package/cjs/Position.cjs +46 -0
- package/cjs/index.cjs +113 -0
- package/cjs/json/nodes/JsonArray.cjs +21 -0
- package/cjs/json/nodes/JsonDocument.cjs +22 -0
- package/cjs/json/nodes/JsonEscapeSequence.cjs +14 -0
- package/cjs/json/nodes/JsonFalse.cjs +14 -0
- package/cjs/json/nodes/JsonKey.cjs +14 -0
- package/cjs/json/nodes/JsonNode.cjs +10 -0
- package/cjs/json/nodes/JsonNull.cjs +14 -0
- package/cjs/json/nodes/JsonNumber.cjs +14 -0
- package/cjs/json/nodes/JsonObject.cjs +21 -0
- package/cjs/json/nodes/JsonProperty.cjs +27 -0
- package/cjs/json/nodes/JsonString.cjs +27 -0
- package/cjs/json/nodes/JsonStringContent.cjs +14 -0
- package/cjs/json/nodes/JsonTrue.cjs +14 -0
- package/cjs/json/nodes/JsonValue.cjs +22 -0
- package/cjs/json/nodes/predicates.cjs +29 -0
- package/cjs/predicates.cjs +14 -0
- package/cjs/traversal/visitor.cjs +493 -0
- package/cjs/yaml/nodes/YamlAlias.cjs +22 -0
- package/cjs/yaml/nodes/YamlAnchor.cjs +22 -0
- package/cjs/yaml/nodes/YamlCollection.cjs +10 -0
- package/cjs/yaml/nodes/YamlComment.cjs +22 -0
- package/cjs/yaml/nodes/YamlDirective.cjs +30 -0
- package/cjs/yaml/nodes/YamlDocument.cjs +14 -0
- package/cjs/yaml/nodes/YamlKeyValuePair.cjs +40 -0
- package/cjs/yaml/nodes/YamlMapping.cjs +24 -0
- package/cjs/yaml/nodes/YamlNode.cjs +28 -0
- package/cjs/yaml/nodes/YamlScalar.cjs +22 -0
- package/cjs/yaml/nodes/YamlSequence.cjs +27 -0
- package/cjs/yaml/nodes/YamlStream.cjs +26 -0
- package/cjs/yaml/nodes/YamlStyle.cjs +33 -0
- package/cjs/yaml/nodes/YamlTag.cjs +32 -0
- package/cjs/yaml/nodes/predicates.cjs +25 -0
- package/cjs/yaml/schemas/ScalarTag.cjs +43 -0
- package/cjs/yaml/schemas/Tag.cjs +14 -0
- package/cjs/yaml/schemas/canonical-format.cjs +129 -0
- package/cjs/yaml/schemas/failsafe/GenericMapping.cjs +29 -0
- package/cjs/yaml/schemas/failsafe/GenericSequence.cjs +29 -0
- package/cjs/yaml/schemas/failsafe/GenericString.cjs +24 -0
- package/cjs/yaml/schemas/failsafe/index.cjs +96 -0
- package/cjs/yaml/schemas/json/Boolean.cjs +30 -0
- package/cjs/yaml/schemas/json/FloatingPoint.cjs +30 -0
- package/cjs/yaml/schemas/json/Integer.cjs +30 -0
- package/cjs/yaml/schemas/json/Null.cjs +29 -0
- package/cjs/yaml/schemas/json/index.cjs +47 -0
- package/dist/apidom-ast.browser.js +21212 -0
- package/dist/apidom-ast.browser.min.js +2 -0
- package/dist/apidom-ast.browser.min.js.LICENSE.txt +6 -0
- package/es/Error.js +19 -0
- package/es/Literal.js +16 -0
- package/es/Node.js +40 -0
- package/es/ParseResult.js +16 -0
- package/es/Position.js +39 -0
- package/es/index.js +39 -0
- package/es/json/nodes/JsonArray.js +15 -0
- package/es/json/nodes/JsonDocument.js +16 -0
- package/es/json/nodes/JsonEscapeSequence.js +8 -0
- package/es/json/nodes/JsonFalse.js +8 -0
- package/es/json/nodes/JsonKey.js +8 -0
- package/es/json/nodes/JsonNode.js +4 -0
- package/es/json/nodes/JsonNull.js +8 -0
- package/es/json/nodes/JsonNumber.js +8 -0
- package/es/json/nodes/JsonObject.js +15 -0
- package/es/json/nodes/JsonProperty.js +21 -0
- package/es/json/nodes/JsonString.js +21 -0
- package/es/json/nodes/JsonStringContent.js +8 -0
- package/es/json/nodes/JsonTrue.js +8 -0
- package/es/json/nodes/JsonValue.js +16 -0
- package/es/json/nodes/predicates.js +13 -0
- package/es/predicates.js +5 -0
- package/es/traversal/visitor.js +483 -0
- package/es/yaml/nodes/YamlAlias.js +16 -0
- package/es/yaml/nodes/YamlAnchor.js +16 -0
- package/es/yaml/nodes/YamlCollection.js +4 -0
- package/es/yaml/nodes/YamlComment.js +16 -0
- package/es/yaml/nodes/YamlDirective.js +24 -0
- package/es/yaml/nodes/YamlDocument.js +8 -0
- package/es/yaml/nodes/YamlKeyValuePair.js +34 -0
- package/es/yaml/nodes/YamlMapping.js +18 -0
- package/es/yaml/nodes/YamlNode.js +22 -0
- package/es/yaml/nodes/YamlScalar.js +16 -0
- package/es/yaml/nodes/YamlSequence.js +21 -0
- package/es/yaml/nodes/YamlStream.js +20 -0
- package/es/yaml/nodes/YamlStyle.js +25 -0
- package/es/yaml/nodes/YamlTag.js +25 -0
- package/es/yaml/nodes/predicates.js +11 -0
- package/es/yaml/schemas/ScalarTag.js +37 -0
- package/es/yaml/schemas/Tag.js +8 -0
- package/es/yaml/schemas/canonical-format.js +122 -0
- package/es/yaml/schemas/failsafe/GenericMapping.js +23 -0
- package/es/yaml/schemas/failsafe/GenericSequence.js +23 -0
- package/es/yaml/schemas/failsafe/GenericString.js +18 -0
- package/es/yaml/schemas/failsafe/index.js +90 -0
- package/es/yaml/schemas/json/Boolean.js +24 -0
- package/es/yaml/schemas/json/FloatingPoint.js +24 -0
- package/es/yaml/schemas/json/Integer.js +24 -0
- package/es/yaml/schemas/json/Null.js +23 -0
- package/es/yaml/schemas/json/index.js +41 -0
- package/package.json +62 -0
- package/types/dist.d.ts +362 -0
@@ -0,0 +1,483 @@
|
|
1
|
+
/**
|
2
|
+
* SPDX-FileCopyrightText: Copyright (c) GraphQL Contributors
|
3
|
+
*
|
4
|
+
* SPDX-License-Identifier: MIT
|
5
|
+
*/
|
6
|
+
|
7
|
+
// getVisitFn :: (Visitor, String, Boolean) -> Function
|
8
|
+
export const getVisitFn = (visitor, type, isLeaving) => {
|
9
|
+
const typeVisitor = visitor[type];
|
10
|
+
if (typeVisitor != null) {
|
11
|
+
if (!isLeaving && typeof typeVisitor === 'function') {
|
12
|
+
// { Type() {} }
|
13
|
+
return typeVisitor;
|
14
|
+
}
|
15
|
+
const typeSpecificVisitor = isLeaving ? typeVisitor.leave : typeVisitor.enter;
|
16
|
+
if (typeof typeSpecificVisitor === 'function') {
|
17
|
+
// { Type: { enter() {}, leave() {} } }
|
18
|
+
return typeSpecificVisitor;
|
19
|
+
}
|
20
|
+
} else {
|
21
|
+
const specificVisitor = isLeaving ? visitor.leave : visitor.enter;
|
22
|
+
if (specificVisitor != null) {
|
23
|
+
if (typeof specificVisitor === 'function') {
|
24
|
+
// { enter() {}, leave() {} }
|
25
|
+
return specificVisitor;
|
26
|
+
}
|
27
|
+
const specificTypeVisitor = specificVisitor[type];
|
28
|
+
if (typeof specificTypeVisitor === 'function') {
|
29
|
+
// { enter: { Type() {} }, leave: { Type() {} } }
|
30
|
+
return specificTypeVisitor;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
return null;
|
35
|
+
};
|
36
|
+
export const BREAK = {};
|
37
|
+
|
38
|
+
// getNodeType :: Node -> String
|
39
|
+
export const getNodeType = node => node === null || node === void 0 ? void 0 : node.type;
|
40
|
+
|
41
|
+
// isNode :: Node -> Boolean
|
42
|
+
export const isNode = node => typeof getNodeType(node) === 'string';
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Creates a new visitor instance which delegates to many visitors to run in
|
46
|
+
* parallel. Each visitor will be visited for each node before moving on.
|
47
|
+
*
|
48
|
+
* If a prior visitor edits a node, no following visitors will see that node.
|
49
|
+
*/
|
50
|
+
export const mergeAll = (visitors, {
|
51
|
+
visitFnGetter = getVisitFn,
|
52
|
+
nodeTypeGetter = getNodeType
|
53
|
+
} = {}) => {
|
54
|
+
const skipping = new Array(visitors.length);
|
55
|
+
return {
|
56
|
+
enter(node, ...rest) {
|
57
|
+
for (let i = 0; i < visitors.length; i += 1) {
|
58
|
+
if (skipping[i] == null) {
|
59
|
+
const fn = visitFnGetter(visitors[i], nodeTypeGetter(node), /* isLeaving */false);
|
60
|
+
if (typeof fn === 'function') {
|
61
|
+
const result = fn.call(visitors[i], node, ...rest);
|
62
|
+
if (result === false) {
|
63
|
+
skipping[i] = node;
|
64
|
+
} else if (result === BREAK) {
|
65
|
+
skipping[i] = BREAK;
|
66
|
+
} else if (result !== undefined) {
|
67
|
+
return result;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
return undefined;
|
73
|
+
},
|
74
|
+
leave(node, ...rest) {
|
75
|
+
for (let i = 0; i < visitors.length; i += 1) {
|
76
|
+
if (skipping[i] == null) {
|
77
|
+
const fn = visitFnGetter(visitors[i], nodeTypeGetter(node), /* isLeaving */true);
|
78
|
+
if (typeof fn === 'function') {
|
79
|
+
const result = fn.call(visitors[i], node, ...rest);
|
80
|
+
if (result === BREAK) {
|
81
|
+
skipping[i] = BREAK;
|
82
|
+
} else if (result !== undefined && result !== false) {
|
83
|
+
return result;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
} else if (skipping[i] === node) {
|
87
|
+
skipping[i] = null;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
return undefined;
|
91
|
+
}
|
92
|
+
};
|
93
|
+
};
|
94
|
+
|
95
|
+
/* eslint-disable no-continue, no-nested-ternary, no-param-reassign */
|
96
|
+
/**
|
97
|
+
* visit() will walk through an AST using a preorder depth first traversal, calling
|
98
|
+
* the visitor's enter function at each node in the traversal, and calling the
|
99
|
+
* leave function after visiting that node and all of its child nodes.
|
100
|
+
*
|
101
|
+
* By returning different values from the enter and leave functions, the
|
102
|
+
* behavior of the visitor can be altered, including skipping over a sub-tree of
|
103
|
+
* the AST (by returning false), editing the AST by returning a value or null
|
104
|
+
* to remove the value, or to stop the whole traversal by returning BREAK.
|
105
|
+
*
|
106
|
+
* When using visit() to edit an AST, the original AST will not be modified, and
|
107
|
+
* a new version of the AST with the changes applied will be returned from the
|
108
|
+
* visit function.
|
109
|
+
*
|
110
|
+
* const editedAST = visit(ast, {
|
111
|
+
* enter(node, key, parent, path, ancestors) {
|
112
|
+
* // @return
|
113
|
+
* // undefined: no action
|
114
|
+
* // false: skip visiting this node
|
115
|
+
* // BREAK: stop visiting altogether
|
116
|
+
* // null: delete this node
|
117
|
+
* // any value: replace this node with the returned value
|
118
|
+
* },
|
119
|
+
* leave(node, key, parent, path, ancestors) {
|
120
|
+
* // @return
|
121
|
+
* // undefined: no action
|
122
|
+
* // false: no action
|
123
|
+
* // BREAK: stop visiting altogether
|
124
|
+
* // null: delete this node
|
125
|
+
* // any value: replace this node with the returned value
|
126
|
+
* }
|
127
|
+
* });
|
128
|
+
*
|
129
|
+
* Alternatively to providing enter() and leave() functions, a visitor can
|
130
|
+
* instead provide functions named the same as the kinds of AST nodes, or
|
131
|
+
* enter/leave visitors at a named key, leading to four permutations of
|
132
|
+
* visitor API:
|
133
|
+
*
|
134
|
+
* 1) Named visitors triggered when entering a node a specific kind.
|
135
|
+
*
|
136
|
+
* visit(ast, {
|
137
|
+
* Kind(node) {
|
138
|
+
* // enter the "Kind" node
|
139
|
+
* }
|
140
|
+
* })
|
141
|
+
*
|
142
|
+
* 2) Named visitors that trigger upon entering and leaving a node of
|
143
|
+
* a specific kind.
|
144
|
+
*
|
145
|
+
* visit(ast, {
|
146
|
+
* Kind: {
|
147
|
+
* enter(node) {
|
148
|
+
* // enter the "Kind" node
|
149
|
+
* }
|
150
|
+
* leave(node) {
|
151
|
+
* // leave the "Kind" node
|
152
|
+
* }
|
153
|
+
* }
|
154
|
+
* })
|
155
|
+
*
|
156
|
+
* 3) Generic visitors that trigger upon entering and leaving any node.
|
157
|
+
*
|
158
|
+
* visit(ast, {
|
159
|
+
* enter(node) {
|
160
|
+
* // enter any node
|
161
|
+
* },
|
162
|
+
* leave(node) {
|
163
|
+
* // leave any node
|
164
|
+
* }
|
165
|
+
* })
|
166
|
+
*
|
167
|
+
* 4) Parallel visitors for entering and leaving nodes of a specific kind.
|
168
|
+
*
|
169
|
+
* visit(ast, {
|
170
|
+
* enter: {
|
171
|
+
* Kind(node) {
|
172
|
+
* // enter the "Kind" node
|
173
|
+
* }
|
174
|
+
* },
|
175
|
+
* leave: {
|
176
|
+
* Kind(node) {
|
177
|
+
* // leave the "Kind" node
|
178
|
+
* }
|
179
|
+
* }
|
180
|
+
* })
|
181
|
+
*
|
182
|
+
* @sig visit :: (Node, Visitor, Options)
|
183
|
+
* @sig Options = { keyMap: Object, state: Object }
|
184
|
+
*/
|
185
|
+
export const visit = (
|
186
|
+
// @ts-ignore
|
187
|
+
root,
|
188
|
+
// @ts-ignore
|
189
|
+
visitor, {
|
190
|
+
keyMap = null,
|
191
|
+
state = {},
|
192
|
+
breakSymbol = BREAK,
|
193
|
+
deleteNodeSymbol = null,
|
194
|
+
skipVisitingNodeSymbol = false,
|
195
|
+
visitFnGetter = getVisitFn,
|
196
|
+
nodeTypeGetter = getNodeType,
|
197
|
+
nodePredicate = isNode,
|
198
|
+
detectCycles = true
|
199
|
+
} = {}) => {
|
200
|
+
const visitorKeys = keyMap || {};
|
201
|
+
let stack;
|
202
|
+
let inArray = Array.isArray(root);
|
203
|
+
let keys = [root];
|
204
|
+
let index = -1;
|
205
|
+
let parent;
|
206
|
+
let edits = [];
|
207
|
+
const path = [];
|
208
|
+
// @ts-ignore
|
209
|
+
const ancestors = [];
|
210
|
+
let newRoot = root;
|
211
|
+
do {
|
212
|
+
index += 1;
|
213
|
+
const isLeaving = index === keys.length;
|
214
|
+
let key;
|
215
|
+
let node;
|
216
|
+
const isEdited = isLeaving && edits.length !== 0;
|
217
|
+
if (isLeaving) {
|
218
|
+
key = ancestors.length === 0 ? undefined : path.pop();
|
219
|
+
node = parent;
|
220
|
+
// @ts-ignore
|
221
|
+
parent = ancestors.pop();
|
222
|
+
if (isEdited) {
|
223
|
+
if (inArray) {
|
224
|
+
// @ts-ignore
|
225
|
+
node = node.slice();
|
226
|
+
} else {
|
227
|
+
// creating clone
|
228
|
+
node = Object.create(Object.getPrototypeOf(node), Object.getOwnPropertyDescriptors(node));
|
229
|
+
}
|
230
|
+
let editOffset = 0;
|
231
|
+
for (let ii = 0; ii < edits.length; ii += 1) {
|
232
|
+
let editKey = edits[ii][0];
|
233
|
+
const editValue = edits[ii][1];
|
234
|
+
if (inArray) {
|
235
|
+
editKey -= editOffset;
|
236
|
+
}
|
237
|
+
if (inArray && editValue === deleteNodeSymbol) {
|
238
|
+
node.splice(editKey, 1);
|
239
|
+
editOffset += 1;
|
240
|
+
} else {
|
241
|
+
node[editKey] = editValue;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
index = stack.index;
|
246
|
+
keys = stack.keys;
|
247
|
+
// @ts-ignore
|
248
|
+
edits = stack.edits;
|
249
|
+
// @ts-ignore
|
250
|
+
inArray = stack.inArray;
|
251
|
+
// @ts-ignore
|
252
|
+
stack = stack.prev;
|
253
|
+
} else {
|
254
|
+
key = parent ? inArray ? index : keys[index] : undefined;
|
255
|
+
node = parent ? parent[key] : newRoot;
|
256
|
+
if (node === deleteNodeSymbol || node === undefined) {
|
257
|
+
continue;
|
258
|
+
}
|
259
|
+
if (parent) {
|
260
|
+
path.push(key);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
if (ancestors.includes(node)) {
|
264
|
+
continue;
|
265
|
+
}
|
266
|
+
let result;
|
267
|
+
if (!Array.isArray(node)) {
|
268
|
+
if (!nodePredicate(node)) {
|
269
|
+
throw new Error(`Invalid AST Node: ${JSON.stringify(node)}`);
|
270
|
+
}
|
271
|
+
// cycle detected; skipping over a sub-tree to avoid recursion
|
272
|
+
if (detectCycles && ancestors.includes(node)) {
|
273
|
+
path.pop();
|
274
|
+
continue;
|
275
|
+
}
|
276
|
+
// call appropriate visitor function if available
|
277
|
+
const visitFn = visitFnGetter(visitor, nodeTypeGetter(node), isLeaving);
|
278
|
+
if (visitFn) {
|
279
|
+
// assign state
|
280
|
+
for (const [stateKey, stateValue] of Object.entries(state)) {
|
281
|
+
visitor[stateKey] = stateValue;
|
282
|
+
}
|
283
|
+
result = visitFn.call(visitor, node, key, parent, path, ancestors);
|
284
|
+
if (result === breakSymbol) {
|
285
|
+
break;
|
286
|
+
}
|
287
|
+
if (result === skipVisitingNodeSymbol) {
|
288
|
+
if (!isLeaving) {
|
289
|
+
path.pop();
|
290
|
+
continue;
|
291
|
+
}
|
292
|
+
} else if (result !== undefined) {
|
293
|
+
edits.push([key, result]);
|
294
|
+
if (!isLeaving) {
|
295
|
+
if (nodePredicate(result)) {
|
296
|
+
node = result;
|
297
|
+
} else {
|
298
|
+
path.pop();
|
299
|
+
continue;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
if (result === undefined && isEdited) {
|
306
|
+
edits.push([key, node]);
|
307
|
+
}
|
308
|
+
if (!isLeaving) {
|
309
|
+
stack = {
|
310
|
+
inArray,
|
311
|
+
index,
|
312
|
+
keys,
|
313
|
+
edits,
|
314
|
+
prev: stack
|
315
|
+
};
|
316
|
+
inArray = Array.isArray(node);
|
317
|
+
// @ts-ignore
|
318
|
+
keys = inArray ? node : visitorKeys[nodeTypeGetter(node)] || [];
|
319
|
+
index = -1;
|
320
|
+
edits = [];
|
321
|
+
if (parent) {
|
322
|
+
ancestors.push(parent);
|
323
|
+
}
|
324
|
+
parent = node;
|
325
|
+
}
|
326
|
+
} while (stack !== undefined);
|
327
|
+
if (edits.length !== 0) {
|
328
|
+
[, newRoot] = edits[edits.length - 1];
|
329
|
+
}
|
330
|
+
return newRoot;
|
331
|
+
};
|
332
|
+
|
333
|
+
/**
|
334
|
+
* Asynchronous version of visit.
|
335
|
+
*/
|
336
|
+
// @ts-ignore
|
337
|
+
visit[Symbol.for('nodejs.util.promisify.custom')] = async (
|
338
|
+
// @ts-ignore
|
339
|
+
root,
|
340
|
+
// @ts-ignore
|
341
|
+
visitor, {
|
342
|
+
keyMap = null,
|
343
|
+
state = {},
|
344
|
+
breakSymbol = BREAK,
|
345
|
+
deleteNodeSymbol = null,
|
346
|
+
skipVisitingNodeSymbol = false,
|
347
|
+
visitFnGetter = getVisitFn,
|
348
|
+
nodeTypeGetter = getNodeType,
|
349
|
+
nodePredicate = isNode,
|
350
|
+
detectCycles = true
|
351
|
+
} = {}) => {
|
352
|
+
const visitorKeys = keyMap || {};
|
353
|
+
let stack;
|
354
|
+
let inArray = Array.isArray(root);
|
355
|
+
let keys = [root];
|
356
|
+
let index = -1;
|
357
|
+
let parent;
|
358
|
+
let edits = [];
|
359
|
+
const path = [];
|
360
|
+
// @ts-ignore
|
361
|
+
const ancestors = [];
|
362
|
+
let newRoot = root;
|
363
|
+
do {
|
364
|
+
index += 1;
|
365
|
+
const isLeaving = index === keys.length;
|
366
|
+
let key;
|
367
|
+
let node;
|
368
|
+
const isEdited = isLeaving && edits.length !== 0;
|
369
|
+
if (isLeaving) {
|
370
|
+
key = ancestors.length === 0 ? undefined : path.pop();
|
371
|
+
node = parent;
|
372
|
+
// @ts-ignore
|
373
|
+
parent = ancestors.pop();
|
374
|
+
if (isEdited) {
|
375
|
+
if (inArray) {
|
376
|
+
// @ts-ignore
|
377
|
+
node = node.slice();
|
378
|
+
} else {
|
379
|
+
// creating clone
|
380
|
+
node = Object.create(Object.getPrototypeOf(node), Object.getOwnPropertyDescriptors(node));
|
381
|
+
}
|
382
|
+
let editOffset = 0;
|
383
|
+
for (let ii = 0; ii < edits.length; ii += 1) {
|
384
|
+
let editKey = edits[ii][0];
|
385
|
+
const editValue = edits[ii][1];
|
386
|
+
if (inArray) {
|
387
|
+
editKey -= editOffset;
|
388
|
+
}
|
389
|
+
if (inArray && editValue === deleteNodeSymbol) {
|
390
|
+
node.splice(editKey, 1);
|
391
|
+
editOffset += 1;
|
392
|
+
} else {
|
393
|
+
node[editKey] = editValue;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
index = stack.index;
|
398
|
+
keys = stack.keys;
|
399
|
+
// @ts-ignore
|
400
|
+
edits = stack.edits;
|
401
|
+
// @ts-ignore
|
402
|
+
inArray = stack.inArray;
|
403
|
+
// @ts-ignore
|
404
|
+
stack = stack.prev;
|
405
|
+
} else {
|
406
|
+
key = parent ? inArray ? index : keys[index] : undefined;
|
407
|
+
node = parent ? parent[key] : newRoot;
|
408
|
+
if (node === deleteNodeSymbol || node === undefined) {
|
409
|
+
continue;
|
410
|
+
}
|
411
|
+
if (parent) {
|
412
|
+
path.push(key);
|
413
|
+
}
|
414
|
+
}
|
415
|
+
let result;
|
416
|
+
if (!Array.isArray(node)) {
|
417
|
+
if (!nodePredicate(node)) {
|
418
|
+
throw new Error(`Invalid AST Node: ${JSON.stringify(node)}`);
|
419
|
+
}
|
420
|
+
// cycle detected; skipping over a sub-tree to avoid recursion
|
421
|
+
if (detectCycles && ancestors.includes(node)) {
|
422
|
+
path.pop();
|
423
|
+
continue;
|
424
|
+
}
|
425
|
+
const visitFn = visitFnGetter(visitor, nodeTypeGetter(node), isLeaving);
|
426
|
+
if (visitFn) {
|
427
|
+
// assign state
|
428
|
+
for (const [stateKey, stateValue] of Object.entries(state)) {
|
429
|
+
visitor[stateKey] = stateValue;
|
430
|
+
}
|
431
|
+
|
432
|
+
// eslint-disable-next-line no-await-in-loop
|
433
|
+
result = await visitFn.call(visitor, node, key, parent, path, ancestors);
|
434
|
+
if (result === breakSymbol) {
|
435
|
+
break;
|
436
|
+
}
|
437
|
+
if (result === skipVisitingNodeSymbol) {
|
438
|
+
if (!isLeaving) {
|
439
|
+
path.pop();
|
440
|
+
continue;
|
441
|
+
}
|
442
|
+
} else if (result !== undefined) {
|
443
|
+
edits.push([key, result]);
|
444
|
+
if (!isLeaving) {
|
445
|
+
if (nodePredicate(result)) {
|
446
|
+
node = result;
|
447
|
+
} else {
|
448
|
+
path.pop();
|
449
|
+
continue;
|
450
|
+
}
|
451
|
+
}
|
452
|
+
}
|
453
|
+
}
|
454
|
+
}
|
455
|
+
if (result === undefined && isEdited) {
|
456
|
+
edits.push([key, node]);
|
457
|
+
}
|
458
|
+
if (!isLeaving) {
|
459
|
+
stack = {
|
460
|
+
inArray,
|
461
|
+
index,
|
462
|
+
keys,
|
463
|
+
edits,
|
464
|
+
prev: stack
|
465
|
+
};
|
466
|
+
inArray = Array.isArray(node);
|
467
|
+
// @ts-ignore
|
468
|
+
keys = inArray ? node : visitorKeys[nodeTypeGetter(node)] || [];
|
469
|
+
index = -1;
|
470
|
+
edits = [];
|
471
|
+
if (parent) {
|
472
|
+
ancestors.push(parent);
|
473
|
+
}
|
474
|
+
parent = node;
|
475
|
+
}
|
476
|
+
} while (stack !== undefined);
|
477
|
+
if (edits.length !== 0) {
|
478
|
+
[, newRoot] = edits[edits.length - 1];
|
479
|
+
}
|
480
|
+
return newRoot;
|
481
|
+
};
|
482
|
+
|
483
|
+
/* eslint-enable */
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import Node from "../../Node.js";
|
3
|
+
const YamlAlias = stampit(Node, {
|
4
|
+
statics: {
|
5
|
+
type: 'alias'
|
6
|
+
},
|
7
|
+
props: {
|
8
|
+
content: null
|
9
|
+
},
|
10
|
+
init({
|
11
|
+
content = null
|
12
|
+
} = {}) {
|
13
|
+
this.content = content;
|
14
|
+
}
|
15
|
+
});
|
16
|
+
export default YamlAlias;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import Node from "../../Node.js";
|
3
|
+
const YamlAnchor = stampit(Node, {
|
4
|
+
statics: {
|
5
|
+
type: 'anchor'
|
6
|
+
},
|
7
|
+
props: {
|
8
|
+
name: null
|
9
|
+
},
|
10
|
+
init({
|
11
|
+
name = null
|
12
|
+
} = {}) {
|
13
|
+
this.name = name;
|
14
|
+
}
|
15
|
+
});
|
16
|
+
export default YamlAnchor;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import Node from "../../Node.js";
|
3
|
+
const YamlComment = stampit(Node, {
|
4
|
+
statics: {
|
5
|
+
type: 'comment'
|
6
|
+
},
|
7
|
+
props: {
|
8
|
+
content: null
|
9
|
+
},
|
10
|
+
init({
|
11
|
+
content = null
|
12
|
+
} = {}) {
|
13
|
+
this.content = content;
|
14
|
+
}
|
15
|
+
});
|
16
|
+
export default YamlComment;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import { mergeRight } from 'ramda';
|
3
|
+
import Node from "../../Node.js";
|
4
|
+
const YamlDirective = stampit(Node, {
|
5
|
+
statics: {
|
6
|
+
type: 'directive'
|
7
|
+
},
|
8
|
+
props: {
|
9
|
+
name: null,
|
10
|
+
parameters: null
|
11
|
+
},
|
12
|
+
init({
|
13
|
+
name = null,
|
14
|
+
parameters = {}
|
15
|
+
} = {}) {
|
16
|
+
this.name = name;
|
17
|
+
this.parameters = mergeRight({
|
18
|
+
version: null,
|
19
|
+
handle: null,
|
20
|
+
prefix: null
|
21
|
+
}, parameters);
|
22
|
+
}
|
23
|
+
});
|
24
|
+
export default YamlDirective;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import Node from "../../Node.js";
|
3
|
+
import YamlStyleModel from "./YamlStyle.js";
|
4
|
+
import { isScalar, isMapping, isSequence, isAlias } from "./predicates.js";
|
5
|
+
const YamlKeyValuePair = stampit(Node, YamlStyleModel, {
|
6
|
+
statics: {
|
7
|
+
type: 'keyValuePair'
|
8
|
+
},
|
9
|
+
propertyDescriptors: {
|
10
|
+
key: {
|
11
|
+
get() {
|
12
|
+
// @ts-ignore
|
13
|
+
return this.children.filter(node => isScalar(node) || isMapping(node) || isSequence(node))[0];
|
14
|
+
},
|
15
|
+
enumerable: true
|
16
|
+
},
|
17
|
+
value: {
|
18
|
+
get() {
|
19
|
+
// @ts-ignore
|
20
|
+
const {
|
21
|
+
key,
|
22
|
+
children
|
23
|
+
} = this;
|
24
|
+
const excludeKeyPredicate = node => node !== key;
|
25
|
+
const valuePredicate = node => isScalar(node) || isMapping(node) || isSequence(node) || isAlias(node);
|
26
|
+
|
27
|
+
// @ts-ignore
|
28
|
+
return children.filter(node => excludeKeyPredicate(node) && valuePredicate(node))[0];
|
29
|
+
},
|
30
|
+
enumerable: true
|
31
|
+
}
|
32
|
+
}
|
33
|
+
});
|
34
|
+
export default YamlKeyValuePair;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import YamlCollection from "./YamlCollection.js";
|
3
|
+
import { isKeyValuePair } from "./predicates.js";
|
4
|
+
const YamlMapping = stampit(YamlCollection, {
|
5
|
+
statics: {
|
6
|
+
type: 'mapping'
|
7
|
+
},
|
8
|
+
propertyDescriptors: {
|
9
|
+
content: {
|
10
|
+
get() {
|
11
|
+
// @ts-ignore
|
12
|
+
return Array.isArray(this.children) ? this.children.filter(isKeyValuePair) : [];
|
13
|
+
},
|
14
|
+
enumerable: true
|
15
|
+
}
|
16
|
+
}
|
17
|
+
});
|
18
|
+
export default YamlMapping;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import Node from "../../Node.js";
|
3
|
+
const YamlNode = stampit(Node, {
|
4
|
+
props: {
|
5
|
+
anchor: null,
|
6
|
+
tag: null,
|
7
|
+
style: null,
|
8
|
+
styleGroup: null
|
9
|
+
},
|
10
|
+
init({
|
11
|
+
anchor = null,
|
12
|
+
tag = null,
|
13
|
+
style = null,
|
14
|
+
styleGroup = null
|
15
|
+
} = {}) {
|
16
|
+
this.anchor = anchor;
|
17
|
+
this.tag = tag;
|
18
|
+
this.style = style;
|
19
|
+
this.styleGroup = styleGroup;
|
20
|
+
}
|
21
|
+
});
|
22
|
+
export default YamlNode;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import YamlNode from "./YamlNode.js";
|
3
|
+
const YamlScalar = stampit(YamlNode, {
|
4
|
+
statics: {
|
5
|
+
type: 'scalar'
|
6
|
+
},
|
7
|
+
props: {
|
8
|
+
content: ''
|
9
|
+
},
|
10
|
+
init({
|
11
|
+
content
|
12
|
+
} = {}) {
|
13
|
+
this.content = content;
|
14
|
+
}
|
15
|
+
});
|
16
|
+
export default YamlScalar;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import stampit from 'stampit';
|
2
|
+
import YamlCollection from "./YamlCollection.js";
|
3
|
+
import { isMapping, isScalar, isSequence, isAlias } from "./predicates.js";
|
4
|
+
const YamlSequence = stampit(YamlCollection, {
|
5
|
+
statics: {
|
6
|
+
type: 'sequence'
|
7
|
+
},
|
8
|
+
propertyDescriptors: {
|
9
|
+
content: {
|
10
|
+
get() {
|
11
|
+
// @ts-ignore
|
12
|
+
const {
|
13
|
+
children
|
14
|
+
} = this;
|
15
|
+
return Array.isArray(children) ? children.filter(node => isSequence(node) || isMapping(node) || isScalar(node) || isAlias(node)) : [];
|
16
|
+
},
|
17
|
+
enumerable: true
|
18
|
+
}
|
19
|
+
}
|
20
|
+
});
|
21
|
+
export default YamlSequence;
|