@bablr/agast-helpers 0.5.3 → 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 +201 -62
- package/lib/symbols.js +4 -11
- package/lib/template.js +83 -69
- package/lib/tree.js +390 -297
- package/package.json +6 -1
package/lib/template.js
CHANGED
|
@@ -1,93 +1,107 @@
|
|
|
1
1
|
import * as t from './builders.js';
|
|
2
2
|
import {
|
|
3
|
-
LiteralTag,
|
|
4
|
-
EmbeddedNode,
|
|
5
3
|
ReferenceTag,
|
|
6
|
-
|
|
7
|
-
OpenFragmentTag,
|
|
4
|
+
ArrayInitializerTag,
|
|
8
5
|
OpenNodeTag,
|
|
6
|
+
CloseNodeTag,
|
|
9
7
|
DoctypeTag,
|
|
10
|
-
|
|
8
|
+
EmbeddedNode,
|
|
9
|
+
GapTag,
|
|
11
10
|
} from './symbols.js';
|
|
12
11
|
import * as btree from './btree.js';
|
|
13
|
-
import { getOpenTag,
|
|
12
|
+
import { getOpenTag, get, isFragmentNode } from './tree.js';
|
|
14
13
|
|
|
15
|
-
const { isArray } = Array;
|
|
16
14
|
const { freeze } = Object;
|
|
17
|
-
const { isFinite } = Number;
|
|
18
|
-
|
|
19
|
-
export const interpolateArray = (fragment) => {
|
|
20
|
-
const value = getRoot(fragment);
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} else {
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
return [value];
|
|
30
|
-
}
|
|
16
|
+
export const buildFilledGapFunction = (expressions) => (value) => {
|
|
17
|
+
expressions.push(value);
|
|
18
|
+
return t.buildGapTag();
|
|
31
19
|
};
|
|
32
20
|
|
|
33
|
-
export function*
|
|
34
|
-
const open = getOpenTag(
|
|
21
|
+
export function* interpolateFragment(node, ref, expressions) {
|
|
22
|
+
const open = getOpenTag(node);
|
|
23
|
+
|
|
24
|
+
if (node.type !== null) throw new Error();
|
|
25
|
+
|
|
26
|
+
const gap = buildFilledGapFunction(expressions);
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
const counters = new Map();
|
|
29
|
+
|
|
30
|
+
if (!open.value.type) {
|
|
37
31
|
let currentRef = null;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
let isFragment = isFragmentNode(node);
|
|
33
|
+
for (let tag of btree.traverse(node.children)) {
|
|
34
|
+
switch (tag.type) {
|
|
35
|
+
case DoctypeTag: {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case OpenNodeTag:
|
|
39
|
+
case CloseNodeTag: {
|
|
40
|
+
if (!isFragment) {
|
|
41
|
+
yield tag;
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
case ReferenceTag: {
|
|
47
|
+
currentRef = tag;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
case ArrayInitializerTag: {
|
|
52
|
+
const { name } = currentRef.value;
|
|
53
|
+
counters.set(name, -1);
|
|
54
|
+
if (name === '.') {
|
|
55
|
+
yield freeze({ ...ref });
|
|
56
|
+
} else {
|
|
57
|
+
yield currentRef;
|
|
58
|
+
}
|
|
59
|
+
yield tag;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case GapTag: {
|
|
64
|
+
const { name, isArray, flags } = currentRef.value;
|
|
65
|
+
|
|
66
|
+
if (name === '.') {
|
|
67
|
+
// TODO check/combine flags
|
|
68
|
+
yield freeze({ ...ref });
|
|
69
|
+
} else {
|
|
70
|
+
yield currentRef;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const count = counters.get(name) + 1;
|
|
46
74
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
counters.set(name, count);
|
|
76
|
+
|
|
77
|
+
const resolvedRef = t.buildReferenceTag(name, isArray, flags, count);
|
|
78
|
+
|
|
79
|
+
yield gap(get(resolvedRef, node));
|
|
80
|
+
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
case EmbeddedNode: {
|
|
85
|
+
const { name } = currentRef.value;
|
|
86
|
+
if (name === '.') {
|
|
87
|
+
yield freeze({ ...ref });
|
|
88
|
+
} else {
|
|
89
|
+
yield currentRef;
|
|
90
|
+
}
|
|
91
|
+
yield gap(tag.value);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
default: {
|
|
96
|
+
yield tag;
|
|
97
|
+
break;
|
|
57
98
|
}
|
|
58
|
-
} else {
|
|
59
|
-
yield child;
|
|
60
99
|
}
|
|
61
100
|
}
|
|
62
101
|
} else if (open.type === OpenNodeTag) {
|
|
63
102
|
yield freeze({ ...ref });
|
|
103
|
+
yield gap(get(ref, node));
|
|
64
104
|
} else {
|
|
65
105
|
throw new Error();
|
|
66
106
|
}
|
|
67
107
|
}
|
|
68
|
-
|
|
69
|
-
const validateTag = (tag) => {
|
|
70
|
-
if (!tag || (tag.type !== LiteralTag && tag.type !== EmbeddedNode)) {
|
|
71
|
-
throw new Error('Invalid tag');
|
|
72
|
-
}
|
|
73
|
-
if (tag.type === EmbeddedNode && !tag.value.flags.escape) {
|
|
74
|
-
throw new Error();
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const interpolateString = (value) => {
|
|
79
|
-
const tags = [];
|
|
80
|
-
if (isArray(value)) {
|
|
81
|
-
for (const element of value) {
|
|
82
|
-
validateTag(element);
|
|
83
|
-
|
|
84
|
-
tags.push(element);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
// we can't safely interpolate strings here, though I wish we could
|
|
88
|
-
validateTag(value);
|
|
89
|
-
tags.push(value);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return t.buildNode('String', 'Content', tags);
|
|
93
|
-
};
|