@bablr/agast-helpers 0.8.0 → 0.9.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 +62 -44
- package/lib/path-facade.js +18 -13
- package/lib/path.js +631 -345
- package/lib/print.js +34 -20
- package/lib/shorthand.js +1 -1
- package/lib/stream.js +37 -165
- package/lib/symbols.js +3 -1
- package/lib/tags.js +236 -0
- package/lib/template.js +11 -7
- package/lib/tree.js +224 -292
- package/package.json +6 -4
- package/lib/children.js +0 -120
package/lib/builders.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { isSymbol } from './object.js';
|
|
2
2
|
import { printType } from './print.js';
|
|
3
3
|
import {
|
|
4
4
|
DoctypeTag,
|
|
@@ -10,56 +10,48 @@ import {
|
|
|
10
10
|
NullTag,
|
|
11
11
|
InitializerTag,
|
|
12
12
|
LiteralTag,
|
|
13
|
-
TokenGroup,
|
|
14
13
|
AttributeDefinition,
|
|
15
14
|
BindingTag,
|
|
15
|
+
Document,
|
|
16
16
|
} from './symbols.js';
|
|
17
17
|
|
|
18
18
|
const { freeze, hasOwn } = Object;
|
|
19
19
|
const { isArray } = Array;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
for (const value of Object.values(properties)) {
|
|
23
|
-
if (isArray(value)) {
|
|
24
|
-
for (let value of btree.traverse(value)) {
|
|
25
|
-
yield value.node;
|
|
26
|
-
}
|
|
27
|
-
} else {
|
|
28
|
-
yield value.node;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const find = (predicate, iterable) => {
|
|
34
|
-
for (const value of iterable) {
|
|
35
|
-
if (predicate(value)) return value;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const buildProperty = (reference, binding, node) => {
|
|
21
|
+
export const buildProperty = (reference, binding = null, node = undefined) => {
|
|
40
22
|
if (node?.binding) throw new Error();
|
|
41
23
|
if (!reference.flags) throw new Error();
|
|
42
|
-
if (!isArray(node) && typeof node === 'object' && !hasOwn(node, '
|
|
24
|
+
if (!isArray(node) && typeof node === 'object' && !hasOwn(node, 'tags')) throw new Error();
|
|
43
25
|
|
|
44
26
|
if (reference.value) throw new Error();
|
|
45
27
|
|
|
46
28
|
return freeze({ reference, binding, node });
|
|
47
29
|
};
|
|
48
30
|
|
|
31
|
+
export const buildPropertyWrapper = (tags, property) => {
|
|
32
|
+
freeze(tags);
|
|
33
|
+
freeze(property);
|
|
34
|
+
|
|
35
|
+
if (![ReferenceTag, ShiftTag].includes(tags[0].type)) throw new Error();
|
|
36
|
+
if (property.node && !(tags[1]?.type === InitializerTag || tags.length === 3)) throw new Error();
|
|
37
|
+
|
|
38
|
+
return freeze({ tags, property });
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const buildDocument = (doctypeTag, fragment) => {
|
|
42
|
+
return freeze({ type: Document, value: freeze({ doctypeTag, fragment }) });
|
|
43
|
+
};
|
|
44
|
+
|
|
49
45
|
export const buildFacadeProperty = (reference, binding, node) => {
|
|
50
46
|
if (node?.binding) throw new Error();
|
|
51
47
|
if (!reference.flags) throw new Error();
|
|
52
|
-
if (!isArray(node) && typeof node === 'object' && !node.
|
|
48
|
+
if (!isArray(node) && typeof node === 'object' && !node.tags) throw new Error();
|
|
53
49
|
|
|
54
50
|
if (reference.value) throw new Error();
|
|
55
51
|
|
|
56
52
|
return freeze({ reference, binding, node });
|
|
57
53
|
};
|
|
58
54
|
|
|
59
|
-
export const buildTokenGroup = (tokens) => {
|
|
60
|
-
return freeze({ type: TokenGroup, value: tokens });
|
|
61
|
-
};
|
|
62
|
-
|
|
63
55
|
export const buildBeginningOfStreamToken = () => {
|
|
64
56
|
return freeze({ type: Symbol.for('@bablr/beginning-of-stream'), value: undefined });
|
|
65
57
|
};
|
|
@@ -71,7 +63,7 @@ export const buildReferenceTag = (
|
|
|
71
63
|
flags = referenceFlags,
|
|
72
64
|
index,
|
|
73
65
|
) => {
|
|
74
|
-
if (type != null && !
|
|
66
|
+
if (type != null && !['.', '#', '@', '_'].includes(type)) throw new Error();
|
|
75
67
|
if (name != null && !isString(name)) throw new Error();
|
|
76
68
|
if (name == null && type == null) throw new Error();
|
|
77
69
|
if (index) throw new Error();
|
|
@@ -86,12 +78,31 @@ export const buildReferenceTag = (
|
|
|
86
78
|
});
|
|
87
79
|
};
|
|
88
80
|
|
|
81
|
+
export const buildReference = (
|
|
82
|
+
type = null,
|
|
83
|
+
name = null,
|
|
84
|
+
isArray = false,
|
|
85
|
+
flags = referenceFlags,
|
|
86
|
+
index,
|
|
87
|
+
) => {
|
|
88
|
+
return buildReferenceTag(type, name, isArray, flags, index).value;
|
|
89
|
+
};
|
|
90
|
+
|
|
89
91
|
export const buildNullTag = () => {
|
|
90
92
|
return freeze({ type: NullTag, value: undefined });
|
|
91
93
|
};
|
|
92
94
|
|
|
95
|
+
export const buildInitializer = (isArray = false) => {
|
|
96
|
+
return freeze({ isArray });
|
|
97
|
+
};
|
|
98
|
+
|
|
93
99
|
export const buildInitializerTag = (isArray = false) => {
|
|
94
|
-
return freeze({ type: InitializerTag, value:
|
|
100
|
+
return freeze({ type: InitializerTag, value: buildInitializer(isArray) });
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const buildBinding = (languagePath = []) => {
|
|
104
|
+
if (!isArray(languagePath)) throw new Error();
|
|
105
|
+
return freeze({ languagePath });
|
|
95
106
|
};
|
|
96
107
|
|
|
97
108
|
export const buildBindingTag = (languagePath = []) => {
|
|
@@ -100,6 +111,7 @@ export const buildBindingTag = (languagePath = []) => {
|
|
|
100
111
|
};
|
|
101
112
|
|
|
102
113
|
export const buildChild = (type, value) => {
|
|
114
|
+
if (!isSymbol(type)) throw new Error();
|
|
103
115
|
return freeze({ type, value });
|
|
104
116
|
};
|
|
105
117
|
|
|
@@ -113,22 +125,31 @@ export const buildShiftTag = (index, height) => {
|
|
|
113
125
|
return freeze({ type: ShiftTag, value: freeze({ index, height }) });
|
|
114
126
|
};
|
|
115
127
|
|
|
116
|
-
export const buildDoctypeTag = (
|
|
128
|
+
export const buildDoctypeTag = (version = 0) => {
|
|
117
129
|
return freeze({
|
|
118
130
|
type: DoctypeTag,
|
|
119
|
-
value: freeze({ doctype: 'cstml', version
|
|
131
|
+
value: freeze({ doctype: 'cstml', version }),
|
|
120
132
|
});
|
|
121
133
|
};
|
|
122
134
|
|
|
123
|
-
export const buildOpenNodeTag = (
|
|
135
|
+
export const buildOpenNodeTag = (
|
|
136
|
+
flags = nodeFlags,
|
|
137
|
+
type = null,
|
|
138
|
+
attributes = {},
|
|
139
|
+
literalValue = null,
|
|
140
|
+
selfClosing = !!literalValue,
|
|
141
|
+
) => {
|
|
124
142
|
if (printType(type).startsWith('https://')) throw new Error();
|
|
143
|
+
if (literalValue && (!isString(literalValue) || !flags.token)) throw new Error();
|
|
125
144
|
|
|
126
145
|
return freeze({
|
|
127
146
|
type: OpenNodeTag,
|
|
128
147
|
value: freeze({
|
|
129
148
|
flags: freeze(flags),
|
|
130
149
|
type: isString(type) ? Symbol.for(type) : type,
|
|
150
|
+
literalValue,
|
|
131
151
|
attributes,
|
|
152
|
+
selfClosing,
|
|
132
153
|
}),
|
|
133
154
|
});
|
|
134
155
|
};
|
|
@@ -145,6 +166,8 @@ export const buildLiteralTag = (value) => {
|
|
|
145
166
|
};
|
|
146
167
|
|
|
147
168
|
export const buildAttributeDefinition = (path, value) => {
|
|
169
|
+
if (!path?.length) throw new Error();
|
|
170
|
+
freeze(path);
|
|
148
171
|
return freeze({ type: AttributeDefinition, value: freeze({ path, value }) });
|
|
149
172
|
};
|
|
150
173
|
|
|
@@ -172,20 +195,15 @@ export const fragmentFlags = freeze({
|
|
|
172
195
|
token: false,
|
|
173
196
|
hasGap: false,
|
|
174
197
|
fragment: true,
|
|
175
|
-
cover:
|
|
198
|
+
cover: true,
|
|
176
199
|
});
|
|
177
200
|
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return flags;
|
|
185
|
-
} else {
|
|
186
|
-
return getFlagsWithGap(flags);
|
|
187
|
-
}
|
|
188
|
-
};
|
|
201
|
+
export const multiFragmentFlags = freeze({
|
|
202
|
+
token: false,
|
|
203
|
+
hasGap: false,
|
|
204
|
+
fragment: true,
|
|
205
|
+
cover: false,
|
|
206
|
+
});
|
|
189
207
|
|
|
190
208
|
export const tokenFlags = freeze({
|
|
191
209
|
token: true,
|
package/lib/path-facade.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CloseNodeTag, ReferenceTag } from './symbols.js';
|
|
1
|
+
import { CloseNodeTag, OpenNodeTag, ReferenceTag } from './symbols.js';
|
|
2
2
|
|
|
3
3
|
export function* allTagPathsFor(range, options = {}) {
|
|
4
4
|
if (range == null) return;
|
|
@@ -6,29 +6,34 @@ export function* allTagPathsFor(range, options = {}) {
|
|
|
6
6
|
const { unshift = false } = options;
|
|
7
7
|
let startPath = range[0];
|
|
8
8
|
let endPath = range[1];
|
|
9
|
-
let
|
|
9
|
+
let tagPath = startPath;
|
|
10
10
|
|
|
11
|
-
while (
|
|
12
|
-
if (
|
|
13
|
-
|
|
11
|
+
while (tagPath) {
|
|
12
|
+
if (tagPath.inner && tagPath.previousSibling.tag.type === ReferenceTag) {
|
|
13
|
+
tagPath = tagPath.inner.tagPathAt(0);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
if (
|
|
16
|
+
if (tagPath.path.depth < startPath.path.depth) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
yield
|
|
20
|
+
yield tagPath;
|
|
21
21
|
|
|
22
|
-
if (
|
|
23
|
-
|
|
22
|
+
if (
|
|
23
|
+
tagPath.tag.type === CloseNodeTag ||
|
|
24
|
+
(tagPath.tag.type === OpenNodeTag && tagPath.tag.value.selfClosing)
|
|
25
|
+
) {
|
|
26
|
+
let propPath = tagPath.path.parentPropertyPath;
|
|
27
|
+
if (endPath && propPath && endPath.equalTo(propPath.path.tagPathAt(propPath.tagsIndex, 2))) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (endPath && path.tag.type === CloseNodeTag && propPath && endPath.equalTo(propPath)) {
|
|
32
|
+
if (endPath && endPath.equalTo(tagPath)) {
|
|
29
33
|
return;
|
|
30
34
|
}
|
|
31
|
-
|
|
35
|
+
|
|
36
|
+
tagPath = unshift ? tagPath.nextUnshifted : tagPath.next;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
|