@bablr/agast-helpers 0.5.2 → 0.6.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/lib/builders.js +69 -215
- package/lib/path.js +921 -14
- package/lib/print.js +91 -70
- package/lib/shorthand.js +11 -31
- package/lib/stream.js +195 -59
- package/lib/symbols.js +4 -11
- package/lib/template.js +83 -69
- package/lib/tree.js +390 -297
- package/package.json +9 -2
package/lib/builders.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import * as sym from './symbols.js';
|
|
2
1
|
import * as btree from './btree.js';
|
|
2
|
+
import { printType } from './print.js';
|
|
3
3
|
import {
|
|
4
4
|
DoctypeTag,
|
|
5
5
|
OpenNodeTag,
|
|
6
6
|
CloseNodeTag,
|
|
7
|
-
OpenFragmentTag,
|
|
8
|
-
CloseFragmentTag,
|
|
9
7
|
ReferenceTag,
|
|
10
8
|
ShiftTag,
|
|
11
9
|
GapTag,
|
|
12
10
|
NullTag,
|
|
13
|
-
|
|
11
|
+
ArrayInitializerTag,
|
|
14
12
|
LiteralTag,
|
|
15
|
-
|
|
16
|
-
EmbeddedExpression,
|
|
13
|
+
EmbeddedObject,
|
|
17
14
|
EmbeddedTag,
|
|
18
15
|
TokenGroup,
|
|
16
|
+
EmbeddedMatcher,
|
|
17
|
+
EmbeddedRegex,
|
|
18
|
+
EmbeddedNode,
|
|
19
19
|
} from './symbols.js';
|
|
20
20
|
|
|
21
21
|
const { freeze } = Object;
|
|
@@ -26,9 +26,11 @@ const isObject = (val) => val !== null && typeof value !== 'object';
|
|
|
26
26
|
function* relatedNodes(properties) {
|
|
27
27
|
for (const value of Object.values(properties)) {
|
|
28
28
|
if (isArray(value)) {
|
|
29
|
-
|
|
29
|
+
for (let value of btree.traverse(value)) {
|
|
30
|
+
yield value.node;
|
|
31
|
+
}
|
|
30
32
|
} else {
|
|
31
|
-
yield value;
|
|
33
|
+
yield value.node;
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -39,13 +41,28 @@ const find = (predicate, iterable) => {
|
|
|
39
41
|
}
|
|
40
42
|
};
|
|
41
43
|
|
|
42
|
-
export const
|
|
43
|
-
if (!isObject(expr))
|
|
44
|
-
return freeze({ type:
|
|
44
|
+
export const buildEmbeddedObject = (expr) => {
|
|
45
|
+
if (!isObject(expr)) throw new Error();
|
|
46
|
+
return freeze({ type: EmbeddedObject, value: expr });
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const buildEmbeddedNode = (node) => {
|
|
50
|
+
if (!isObject(node)) throw new Error();
|
|
51
|
+
return freeze({ type: EmbeddedNode, value: node });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const buildEmbeddedMatcher = (node) => {
|
|
55
|
+
if (!isObject(node)) throw new Error();
|
|
56
|
+
return freeze({ type: EmbeddedMatcher, value: node });
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const buildEmbeddedRegex = (node) => {
|
|
60
|
+
if (!isObject(node)) throw new Error();
|
|
61
|
+
return freeze({ type: EmbeddedRegex, value: node });
|
|
45
62
|
};
|
|
46
63
|
|
|
47
64
|
export const buildEmbeddedTag = (tag) => {
|
|
48
|
-
if (!isObject(tag))
|
|
65
|
+
if (!isObject(tag)) throw new Error();
|
|
49
66
|
return freeze({ type: EmbeddedTag, value: tag });
|
|
50
67
|
};
|
|
51
68
|
|
|
@@ -57,18 +74,7 @@ export const buildWriteEffect = (text, options = {}) => {
|
|
|
57
74
|
return buildEffect(
|
|
58
75
|
freeze({
|
|
59
76
|
verb: 'write',
|
|
60
|
-
value:
|
|
61
|
-
freeze({ text, options: buildEmbeddedExpression(freeze(options)) }),
|
|
62
|
-
),
|
|
63
|
-
}),
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const buildYieldEffect = (tag) => {
|
|
68
|
-
return buildEffect(
|
|
69
|
-
freeze({
|
|
70
|
-
verb: 'yield',
|
|
71
|
-
value: buildEmbeddedTag(freeze(tag)),
|
|
77
|
+
value: buildEmbeddedObject(freeze({ text, options: buildEmbeddedObject(freeze(options)) })),
|
|
72
78
|
}),
|
|
73
79
|
);
|
|
74
80
|
};
|
|
@@ -77,7 +83,7 @@ export const buildAnsiPushEffect = (spans = '') => {
|
|
|
77
83
|
return buildEffect(
|
|
78
84
|
freeze({
|
|
79
85
|
verb: 'ansi-push',
|
|
80
|
-
value:
|
|
86
|
+
value: buildEmbeddedObject(
|
|
81
87
|
freeze({ spans: spans === '' ? freeze([]) : freeze(spans.split(' ')) }),
|
|
82
88
|
),
|
|
83
89
|
}),
|
|
@@ -100,28 +106,27 @@ export const buildBeginningOfStreamToken = () => {
|
|
|
100
106
|
return freeze({ type: Symbol.for('@bablr/beginning-of-stream'), value: undefined });
|
|
101
107
|
};
|
|
102
108
|
|
|
103
|
-
export const buildReferenceTag = (name, isArray = false,
|
|
104
|
-
|
|
109
|
+
export const buildReferenceTag = (name, isArray = false, flags = referenceFlags, index = null) => {
|
|
110
|
+
if (name == null || !/[a-zA-Z.#@]/.test(name)) throw new Error('reference must have a name');
|
|
111
|
+
if (index != null && !Number.isFinite(index)) throw new Error();
|
|
112
|
+
return freeze({ type: ReferenceTag, value: freeze({ name, isArray, index, flags }) });
|
|
105
113
|
};
|
|
106
114
|
|
|
107
115
|
export const buildNullTag = () => {
|
|
108
116
|
return freeze({ type: NullTag, value: undefined });
|
|
109
117
|
};
|
|
110
118
|
|
|
111
|
-
export const
|
|
112
|
-
return freeze({ type:
|
|
119
|
+
export const buildArrayInitializerTag = () => {
|
|
120
|
+
return freeze({ type: ArrayInitializerTag, value: undefined });
|
|
113
121
|
};
|
|
114
122
|
|
|
115
123
|
export const buildGapTag = () => {
|
|
116
124
|
return freeze({ type: GapTag, value: undefined });
|
|
117
125
|
};
|
|
118
126
|
|
|
119
|
-
export const buildShiftTag = () => {
|
|
120
|
-
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export const buildEmbeddedNode = (node) => {
|
|
124
|
-
return freeze({ type: EmbeddedNode, value: node });
|
|
127
|
+
export const buildShiftTag = (index) => {
|
|
128
|
+
if (!Number.isFinite(index)) throw new Error();
|
|
129
|
+
return freeze({ type: ShiftTag, value: freeze({ index }) });
|
|
125
130
|
};
|
|
126
131
|
|
|
127
132
|
export const buildDoctypeTag = (attributes = {}) => {
|
|
@@ -131,37 +136,27 @@ export const buildDoctypeTag = (attributes = {}) => {
|
|
|
131
136
|
});
|
|
132
137
|
};
|
|
133
138
|
|
|
134
|
-
export const
|
|
139
|
+
export const buildOpenNodeTag = (
|
|
140
|
+
flags = nodeFlags,
|
|
141
|
+
language = null,
|
|
142
|
+
type = null,
|
|
143
|
+
attributes = {},
|
|
144
|
+
) => {
|
|
145
|
+
if (printType(type).startsWith('https://')) throw new Error();
|
|
146
|
+
|
|
135
147
|
return freeze({
|
|
136
148
|
type: OpenNodeTag,
|
|
137
149
|
value: freeze({
|
|
138
150
|
flags: freeze(flags),
|
|
139
151
|
language,
|
|
140
|
-
type,
|
|
152
|
+
type: isString(type) ? Symbol.for(type) : type,
|
|
141
153
|
attributes,
|
|
142
154
|
}),
|
|
143
155
|
});
|
|
144
156
|
};
|
|
145
157
|
|
|
146
|
-
export const
|
|
147
|
-
return freeze({ type: CloseNodeTag, value:
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
export const buildFragmentOpenTag = (flags = {}) => {
|
|
151
|
-
return freeze({
|
|
152
|
-
type: OpenFragmentTag,
|
|
153
|
-
value: freeze({
|
|
154
|
-
flags: freeze(flags),
|
|
155
|
-
}),
|
|
156
|
-
});
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export const buildFragmentCloseTag = (type = null, language = null) => {
|
|
160
|
-
return freeze({ type: CloseFragmentTag, value: freeze({ language, type }) });
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
export const wrapFragment = (node) => {
|
|
164
|
-
return buildFragment([buildReferenceTag('.')], { '.': node });
|
|
158
|
+
export const buildCloseNodeTag = () => {
|
|
159
|
+
return freeze({ type: CloseNodeTag, value: undefined });
|
|
165
160
|
};
|
|
166
161
|
|
|
167
162
|
const isString = (val) => typeof val === 'string';
|
|
@@ -171,191 +166,50 @@ export const buildLiteralTag = (value) => {
|
|
|
171
166
|
return freeze({ type: LiteralTag, value });
|
|
172
167
|
};
|
|
173
168
|
|
|
174
|
-
export const buildNodeWithFlags = (
|
|
175
|
-
flags,
|
|
176
|
-
language,
|
|
177
|
-
type,
|
|
178
|
-
children = [],
|
|
179
|
-
properties = {},
|
|
180
|
-
attributes = {},
|
|
181
|
-
) => {
|
|
182
|
-
const openTag = buildNodeOpenTag(flags, language, type, attributes);
|
|
183
|
-
const closeTag = buildNodeCloseTag(type);
|
|
184
|
-
|
|
185
|
-
return freeze({
|
|
186
|
-
flags,
|
|
187
|
-
language,
|
|
188
|
-
type,
|
|
189
|
-
children: btree.addAt(0, btree.addAt(btree.getSum(children), children, closeTag), openTag),
|
|
190
|
-
properties: freeze(properties),
|
|
191
|
-
attributes: freeze(attributes),
|
|
192
|
-
});
|
|
193
|
-
};
|
|
194
|
-
|
|
195
169
|
const flagsWithGap = new WeakMap();
|
|
196
170
|
|
|
197
|
-
export const getFlagsWithGap = (flags) =>
|
|
171
|
+
export const getFlagsWithGap = (flags) => {
|
|
172
|
+
let gapFlags = flagsWithGap.get(flags);
|
|
173
|
+
if (!gapFlags) {
|
|
174
|
+
gapFlags = { ...flags, hasGap: true };
|
|
175
|
+
flagsWithGap.set(flags, gapFlags);
|
|
176
|
+
}
|
|
177
|
+
return gapFlags;
|
|
178
|
+
};
|
|
198
179
|
|
|
199
180
|
export const nodeFlags = freeze({
|
|
200
181
|
token: false,
|
|
201
|
-
escape: false,
|
|
202
|
-
trivia: false,
|
|
203
|
-
expression: false,
|
|
204
182
|
hasGap: false,
|
|
205
183
|
});
|
|
206
184
|
|
|
207
|
-
const hasGap = (
|
|
185
|
+
const hasGap = (properties) => {
|
|
208
186
|
return find((node) => node.flags.hasGap, relatedNodes(properties));
|
|
209
187
|
};
|
|
210
188
|
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
if (!gapFlags) {
|
|
214
|
-
gapFlags = { ...flags, hasGap: true };
|
|
215
|
-
flagsWithGap.set(flags, gapFlags);
|
|
216
|
-
}
|
|
217
|
-
return gapFlags;
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const getFlags = (flags, children, properties) => {
|
|
221
|
-
if (!hasGap(flags, children, properties)) {
|
|
189
|
+
const getFlags = (flags, properties) => {
|
|
190
|
+
if (!hasGap(properties)) {
|
|
222
191
|
return flags;
|
|
223
192
|
} else {
|
|
224
|
-
return
|
|
193
|
+
return getFlagsWithGap(flags);
|
|
225
194
|
}
|
|
226
195
|
};
|
|
227
196
|
|
|
228
|
-
export const
|
|
229
|
-
const flags = getFlags(nodeFlags, children, properties);
|
|
230
|
-
return buildNodeWithFlags(flags, language, type, children, properties, attributes);
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
export const buildFragmentWithFlags = (flags, children = [], properties = {}, attributes = {}) => {
|
|
234
|
-
const doctypeTag = buildDoctypeTag(attributes);
|
|
235
|
-
const openTag = buildFragmentOpenTag(flags);
|
|
236
|
-
const closeTag = buildFragmentCloseTag();
|
|
237
|
-
|
|
238
|
-
return freeze({
|
|
239
|
-
flags,
|
|
240
|
-
children: btree.addAt(
|
|
241
|
-
0,
|
|
242
|
-
btree.addAt(0, btree.addAt(btree.getSum(children), children, closeTag), openTag),
|
|
243
|
-
doctypeTag,
|
|
244
|
-
),
|
|
245
|
-
properties: freeze(properties),
|
|
246
|
-
attributes: freeze(attributes),
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
export const buildFragment = (children = [], properties = {}, attributes = {}) => {
|
|
251
|
-
const flags = getFlags(nodeFlags, children, properties);
|
|
252
|
-
return buildFragmentWithFlags(flags, children, properties, attributes);
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
export const syntacticFlags = freeze({
|
|
197
|
+
export const tokenFlags = freeze({
|
|
256
198
|
token: true,
|
|
257
|
-
escape: false,
|
|
258
|
-
trivia: false,
|
|
259
|
-
expression: false,
|
|
260
199
|
hasGap: false,
|
|
261
200
|
});
|
|
262
201
|
|
|
263
|
-
export const
|
|
264
|
-
return buildNodeWithFlags(syntacticFlags, language, type, [buildLiteralTag(value)]);
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
export const escapeFlags = freeze({
|
|
268
|
-
token: false,
|
|
269
|
-
escape: true,
|
|
270
|
-
trivia: false,
|
|
271
|
-
expression: false,
|
|
272
|
-
hasGap: false,
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
export const buildEscapeNode = (
|
|
276
|
-
language,
|
|
277
|
-
type,
|
|
278
|
-
children = [],
|
|
279
|
-
properties = {},
|
|
280
|
-
attributes = {},
|
|
281
|
-
) => {
|
|
282
|
-
const flags = getFlags(escapeFlags, children, properties);
|
|
283
|
-
return buildNodeWithFlags(flags, language, type, children, properties, attributes);
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
export const syntacticEscapeFlags = freeze({
|
|
287
|
-
token: true,
|
|
288
|
-
escape: true,
|
|
289
|
-
trivia: false,
|
|
202
|
+
export const referenceFlags = freeze({
|
|
290
203
|
expression: false,
|
|
291
204
|
hasGap: false,
|
|
292
205
|
});
|
|
293
206
|
|
|
294
|
-
export const
|
|
295
|
-
language,
|
|
296
|
-
type,
|
|
297
|
-
children = [],
|
|
298
|
-
properties = {},
|
|
299
|
-
attributes = {},
|
|
300
|
-
) => {
|
|
301
|
-
return buildNodeWithFlags(syntacticEscapeFlags, language, type, children, properties, attributes);
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
export const syntacticTriviaFlags = freeze({
|
|
305
|
-
token: true,
|
|
306
|
-
escape: false,
|
|
307
|
-
trivia: true,
|
|
207
|
+
export const gapReferenceFlags = freeze({
|
|
308
208
|
expression: false,
|
|
309
|
-
hasGap:
|
|
209
|
+
hasGap: true,
|
|
310
210
|
});
|
|
311
211
|
|
|
312
|
-
export const
|
|
313
|
-
|
|
314
|
-
type,
|
|
315
|
-
children = [],
|
|
316
|
-
properties = {},
|
|
317
|
-
attributes = {},
|
|
318
|
-
) => {
|
|
319
|
-
return buildNodeWithFlags(syntacticTriviaFlags, language, type, children, properties, attributes);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
export const triviaFlags = freeze({
|
|
323
|
-
token: false,
|
|
324
|
-
escape: false,
|
|
325
|
-
trivia: true,
|
|
326
|
-
expression: false,
|
|
212
|
+
export const expressionReferenceFlags = freeze({
|
|
213
|
+
expression: true,
|
|
327
214
|
hasGap: false,
|
|
328
215
|
});
|
|
329
|
-
|
|
330
|
-
export const buildTriviaNode = (
|
|
331
|
-
language,
|
|
332
|
-
type,
|
|
333
|
-
children = [],
|
|
334
|
-
properties = {},
|
|
335
|
-
attributes = {},
|
|
336
|
-
) => {
|
|
337
|
-
const flags = getFlags(triviaFlags, children, properties);
|
|
338
|
-
return buildNodeWithFlags(flags, language, type, children, properties, attributes);
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
export const buildNullNode = (nullToken = buildNullTag()) => {
|
|
342
|
-
return freeze({
|
|
343
|
-
flags: nodeFlags,
|
|
344
|
-
language: null,
|
|
345
|
-
type: sym.null,
|
|
346
|
-
children: btree.freeze([nullToken]),
|
|
347
|
-
properties: freeze({}),
|
|
348
|
-
attributes: freeze({}),
|
|
349
|
-
});
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
export const buildGapNode = (gapToken = buildGapTag()) => {
|
|
353
|
-
return freeze({
|
|
354
|
-
flags: getGapFlags(nodeFlags),
|
|
355
|
-
language: null,
|
|
356
|
-
type: sym.gap,
|
|
357
|
-
children: btree.freeze([gapToken]),
|
|
358
|
-
properties: freeze({}),
|
|
359
|
-
attributes: freeze({}),
|
|
360
|
-
});
|
|
361
|
-
};
|