@bablr/agast-helpers 0.7.0 → 0.8.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 +70 -27
- package/lib/children.js +120 -0
- package/lib/object.js +86 -0
- package/lib/path-facade.js +39 -0
- package/lib/path.js +386 -448
- package/lib/print.js +53 -91
- package/lib/shorthand.js +26 -1
- package/lib/stream.js +33 -13
- package/lib/symbols.js +3 -1
- package/lib/template.js +23 -36
- package/lib/tree.js +368 -122
- package/package.json +8 -5
- package/lib/sumtree.js +0 -62
package/lib/print.js
CHANGED
|
@@ -8,8 +8,10 @@ import {
|
|
|
8
8
|
NullTag,
|
|
9
9
|
InitializerTag,
|
|
10
10
|
LiteralTag,
|
|
11
|
+
AttributeDefinition,
|
|
12
|
+
BindingTag,
|
|
11
13
|
} from './symbols.js';
|
|
12
|
-
import {
|
|
14
|
+
import { referenceFlags } from './tree.js';
|
|
13
15
|
|
|
14
16
|
let { isInteger, isFinite } = Number;
|
|
15
17
|
let { isArray } = Array;
|
|
@@ -30,39 +32,6 @@ export const printObject = (obj) => {
|
|
|
30
32
|
: '{}';
|
|
31
33
|
};
|
|
32
34
|
|
|
33
|
-
export const printPropertyMatcher = (matcher) => {
|
|
34
|
-
let { refMatcher, nodeMatcher } = matcher;
|
|
35
|
-
let ref = { type: ReferenceTag, value: refMatcher };
|
|
36
|
-
let refPart = refMatcher && !isEmptyReference(ref) ? `${printReferenceTag(ref)} ` : '';
|
|
37
|
-
let nodePart;
|
|
38
|
-
|
|
39
|
-
if (isArray(nodeMatcher)) {
|
|
40
|
-
if (nodeMatcher.length) throw new Error();
|
|
41
|
-
nodePart = '[]';
|
|
42
|
-
} else if (isGapNode(nodeMatcher)) {
|
|
43
|
-
nodePart = '<//>';
|
|
44
|
-
} else if (isNullNode(nodeMatcher)) {
|
|
45
|
-
nodePart = 'null';
|
|
46
|
-
} else {
|
|
47
|
-
nodePart = printOpenNodeMatcher(nodeMatcher);
|
|
48
|
-
}
|
|
49
|
-
return `${refPart}${nodePart}`;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const printOpenNodeMatcher = (matcher) => {
|
|
53
|
-
let { flags, language: tagLanguage, type, attributes, intrinsicValue } = matcher;
|
|
54
|
-
|
|
55
|
-
let printedAttributes = printAttributes(attributes);
|
|
56
|
-
let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
|
|
57
|
-
|
|
58
|
-
let intrinsicFrag = intrinsicValue
|
|
59
|
-
? ` ${isString(intrinsicValue) ? printExpression(intrinsicValue) : printSource(intrinsicValue)}`
|
|
60
|
-
: '';
|
|
61
|
-
let typeFrag = type !== Symbol.for('@bablr/fragment') ? printTagPath(tagLanguage, type) : ' ';
|
|
62
|
-
|
|
63
|
-
return `<${printNodeFlags(flags)}${typeFrag}${intrinsicFrag}${attributesFrag}/>`;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
35
|
export const printExpression = (expr) => {
|
|
67
36
|
if (isString(expr)) {
|
|
68
37
|
return printString(expr);
|
|
@@ -91,19 +60,8 @@ export const printAttributes = (attributes) => {
|
|
|
91
60
|
return !printed || printed === '{}' ? '' : printed;
|
|
92
61
|
};
|
|
93
62
|
|
|
94
|
-
export const
|
|
95
|
-
|
|
96
|
-
return printSingleString(language);
|
|
97
|
-
} else {
|
|
98
|
-
return language.join('.');
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export const printTagPath = (language, type) => {
|
|
103
|
-
return [
|
|
104
|
-
...when(type && language?.length, () => [printLanguage(language)]),
|
|
105
|
-
...when(type, [printType(type)]),
|
|
106
|
-
].join(':');
|
|
63
|
+
export const printIdentifierPath = (path) => {
|
|
64
|
+
return path.map(printIdentifier).join('.');
|
|
107
65
|
};
|
|
108
66
|
|
|
109
67
|
let escapeReplacer = (esc) => {
|
|
@@ -122,6 +80,14 @@ let escapeReplacer = (esc) => {
|
|
|
122
80
|
}
|
|
123
81
|
};
|
|
124
82
|
|
|
83
|
+
export const printIdentifier = (id) => {
|
|
84
|
+
return /^[a-zA-Z\u{80}-\u{10ffff}][a-zA-Z\u{80}-\u{10ffff}0-9_-]+$/u.test(id)
|
|
85
|
+
? id
|
|
86
|
+
: `\`${id
|
|
87
|
+
.replace(/[`\\]/g, '\\`')
|
|
88
|
+
.replace(/[\x00-\x20\x7f]/g, (value) => `\\u00${value.toString(16)}`)}\``;
|
|
89
|
+
};
|
|
90
|
+
|
|
125
91
|
export const printSingleString = (str) => {
|
|
126
92
|
return `'${str.replace(/['\\\0\r\n\t\u0000-\u001A]/g, escapeReplacer)}'`;
|
|
127
93
|
};
|
|
@@ -159,10 +125,18 @@ export const printShiftTag = (tag) => {
|
|
|
159
125
|
export const printReferenceTag = (tag) => {
|
|
160
126
|
if (tag?.type !== ReferenceTag) throw new Error();
|
|
161
127
|
|
|
162
|
-
let { name, isArray, flags
|
|
163
|
-
let pathBraces = isArray ? `[
|
|
128
|
+
let { type, name, isArray, flags } = tag.value;
|
|
129
|
+
let pathBraces = isArray ? `[]` : '';
|
|
164
130
|
|
|
165
|
-
|
|
131
|
+
if (type && name) throw new Error();
|
|
132
|
+
if (type && !['.', '#', '@'].includes(type)) throw new Error();
|
|
133
|
+
|
|
134
|
+
return `${type || printIdentifier(name) || ''}${pathBraces}${printReferenceFlags(flags)}:`;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const printBindingTag = (tag) => {
|
|
138
|
+
let { languagePath } = tag.value;
|
|
139
|
+
return `:${languagePath ? printIdentifierPath(languagePath) : ''}:`;
|
|
166
140
|
};
|
|
167
141
|
|
|
168
142
|
export const printNullTag = (tag) => {
|
|
@@ -177,7 +151,7 @@ export const printType = (type) => {
|
|
|
177
151
|
return typeof type === 'string'
|
|
178
152
|
? type
|
|
179
153
|
: typeof type === 'symbol'
|
|
180
|
-
? type.description
|
|
154
|
+
? printIdentifier(type.description)
|
|
181
155
|
: String(type);
|
|
182
156
|
};
|
|
183
157
|
|
|
@@ -209,40 +183,35 @@ export const printNodeFlags = (flags) => {
|
|
|
209
183
|
if (flags.cover && !flags.fragment) throw new Error();
|
|
210
184
|
let star = flags.token ? '*' : '';
|
|
211
185
|
let dollar = flags.hasGap ? '$' : '';
|
|
212
|
-
let frag = flags.fragment ? '_' : '';
|
|
213
|
-
let cover = flags.cover ? '_' : '';
|
|
214
186
|
|
|
215
|
-
return `${star}${dollar}
|
|
187
|
+
return `${star}${dollar}`;
|
|
216
188
|
};
|
|
217
189
|
|
|
218
190
|
export const printOpenNodeTag = (tag) => {
|
|
219
191
|
if (tag?.type !== OpenNodeTag) throw new Error();
|
|
220
192
|
|
|
221
|
-
let { flags,
|
|
193
|
+
let { flags, type, attributes } = tag.value;
|
|
222
194
|
|
|
223
195
|
if (!type) {
|
|
224
|
-
return `<${printNodeFlags(flags)}>`;
|
|
196
|
+
return `<${printNodeFlags(flags)}_>`;
|
|
225
197
|
}
|
|
226
198
|
|
|
227
199
|
let printedAttributes = printAttributes(attributes);
|
|
228
200
|
let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
|
|
229
201
|
|
|
230
|
-
return `<${printNodeFlags(flags)}${
|
|
202
|
+
return `<${printNodeFlags(flags)}${printType(type)}${attributesFrag}>`;
|
|
231
203
|
};
|
|
232
204
|
|
|
233
205
|
export const printSelfClosingNodeTag = (tag, intrinsicValue) => {
|
|
234
206
|
if (tag?.type !== OpenNodeTag) throw new Error();
|
|
235
207
|
|
|
236
|
-
let { flags,
|
|
208
|
+
let { flags, type, attributes } = tag.value;
|
|
237
209
|
|
|
238
210
|
let printedAttributes = printAttributes(attributes);
|
|
239
211
|
let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
|
|
240
212
|
let intrinsicFrag = intrinsicValue ? ` ${printString(intrinsicValue)}` : '';
|
|
241
213
|
|
|
242
|
-
return `<${printNodeFlags(flags)}${
|
|
243
|
-
tagLanguage,
|
|
244
|
-
type,
|
|
245
|
-
)}${intrinsicFrag}${attributesFrag} />`;
|
|
214
|
+
return `<${printNodeFlags(flags)}${printType(type)}${intrinsicFrag}${attributesFrag} />`;
|
|
246
215
|
};
|
|
247
216
|
|
|
248
217
|
export const printCloseNodeTag = (tag) => {
|
|
@@ -251,38 +220,31 @@ export const printCloseNodeTag = (tag) => {
|
|
|
251
220
|
return `</>`;
|
|
252
221
|
};
|
|
253
222
|
|
|
254
|
-
export const
|
|
255
|
-
if (
|
|
256
|
-
|
|
257
|
-
switch (tag?.type || NullTag) {
|
|
258
|
-
case NullTag:
|
|
259
|
-
return printNullTag(tag);
|
|
260
|
-
|
|
261
|
-
case GapTag:
|
|
262
|
-
return printGapTag(tag);
|
|
263
|
-
|
|
264
|
-
case InitializerTag:
|
|
265
|
-
return printInitializerTag(tag);
|
|
223
|
+
export const printAttributeDefinition = (tag) => {
|
|
224
|
+
if (tag?.type !== AttributeDefinition) throw new Error();
|
|
225
|
+
let { path, value } = tag.value;
|
|
266
226
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
case LiteralTag:
|
|
271
|
-
return printLiteralTag(tag);
|
|
272
|
-
|
|
273
|
-
case DoctypeTag:
|
|
274
|
-
return printDoctypeTag(tag);
|
|
227
|
+
return `{ ${printIdentifierPath(path)}: ${printExpression(value)} }`;
|
|
228
|
+
};
|
|
275
229
|
|
|
276
|
-
|
|
277
|
-
|
|
230
|
+
const printers = {
|
|
231
|
+
[NullTag]: printNullTag,
|
|
232
|
+
[GapTag]: printGapTag,
|
|
233
|
+
[BindingTag]: printBindingTag,
|
|
234
|
+
[InitializerTag]: printInitializerTag,
|
|
235
|
+
[ShiftTag]: printShiftTag,
|
|
236
|
+
[LiteralTag]: printLiteralTag,
|
|
237
|
+
[DoctypeTag]: printDoctypeTag,
|
|
238
|
+
[ReferenceTag]: printReferenceTag,
|
|
239
|
+
[OpenNodeTag]: printOpenNodeTag,
|
|
240
|
+
[CloseNodeTag]: printCloseNodeTag,
|
|
241
|
+
[AttributeDefinition]: printAttributeDefinition,
|
|
242
|
+
};
|
|
278
243
|
|
|
279
|
-
|
|
280
|
-
|
|
244
|
+
export const printTag = (tag) => {
|
|
245
|
+
if (!isObject(tag)) throw new Error();
|
|
281
246
|
|
|
282
|
-
|
|
283
|
-
return printCloseNodeTag(tag);
|
|
247
|
+
let printer = printers[tag?.type];
|
|
284
248
|
|
|
285
|
-
|
|
286
|
-
throw new Error();
|
|
287
|
-
}
|
|
249
|
+
return printer(tag);
|
|
288
250
|
};
|
package/lib/shorthand.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
buildLiteralTag,
|
|
7
7
|
buildInitializerTag,
|
|
8
8
|
} from './builders.js';
|
|
9
|
-
import {
|
|
9
|
+
import { buildReferenceTag, treeFromStreamSync } from './tree.js';
|
|
10
10
|
|
|
11
11
|
export * from './builders.js';
|
|
12
12
|
|
|
@@ -23,6 +23,31 @@ const stripArray = (val) => {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
export const parseReference = (str) => {
|
|
27
|
+
let {
|
|
28
|
+
1: type,
|
|
29
|
+
2: name,
|
|
30
|
+
3: isArray,
|
|
31
|
+
4: index,
|
|
32
|
+
5: expressionToken,
|
|
33
|
+
6: hasGapToken,
|
|
34
|
+
} = /^\s*(?:([.#@])|([a-zA-Z\u{80}-\u{10ffff}][a-zA-Z0-9_\u{80}-\u{10ffff}-]*))\s*(\[\s*(\d+\s*)?\])?\s*(\+)?(\$)?\s*$/u.exec(
|
|
35
|
+
str,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
let flags = {
|
|
39
|
+
expression: !!expressionToken,
|
|
40
|
+
hasGap: !!hasGapToken,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
index = index ? parseInt(index, 10) : null;
|
|
44
|
+
isArray = !!isArray;
|
|
45
|
+
type = type || null;
|
|
46
|
+
name = name || null;
|
|
47
|
+
|
|
48
|
+
return buildReferenceTag(type, name, isArray, flags, index);
|
|
49
|
+
};
|
|
50
|
+
|
|
26
51
|
export const ref = (path) => {
|
|
27
52
|
return parseReference(isArray(path) ? path[0] : path);
|
|
28
53
|
};
|
package/lib/stream.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Coroutine } from '@bablr/coroutine';
|
|
2
2
|
import emptyStack from '@iter-tools/imm-stack';
|
|
3
3
|
import { printSelfClosingNodeTag, printTag } from './print.js';
|
|
4
|
-
import { buildTokenGroup } from './builders.js';
|
|
4
|
+
import { buildOpenNodeTag, buildTokenGroup } from './builders.js';
|
|
5
5
|
import {
|
|
6
6
|
DoctypeTag,
|
|
7
7
|
OpenNodeTag,
|
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
InitializerTag,
|
|
14
14
|
LiteralTag,
|
|
15
15
|
TokenGroup,
|
|
16
|
+
BindingTag,
|
|
17
|
+
AttributeDefinition,
|
|
16
18
|
} from './symbols.js';
|
|
17
19
|
|
|
18
20
|
export * from './print.js';
|
|
@@ -120,6 +122,10 @@ export class StreamGenerator {
|
|
|
120
122
|
return this.generator.return(value);
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
[Symbol.iterator]() {
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
123
129
|
[Symbol.for('@@streamIterator')]() {
|
|
124
130
|
return this;
|
|
125
131
|
}
|
|
@@ -175,7 +181,7 @@ function* __isEmpty(tags) {
|
|
|
175
181
|
case OpenNodeTag:
|
|
176
182
|
++depth;
|
|
177
183
|
|
|
178
|
-
if (depth === 0 && ref.value.
|
|
184
|
+
if (depth === 0 && ref.value.type === '@') {
|
|
179
185
|
return false;
|
|
180
186
|
}
|
|
181
187
|
|
|
@@ -319,8 +325,17 @@ function* __prettyGroupTags(tags) {
|
|
|
319
325
|
|
|
320
326
|
if (
|
|
321
327
|
(tag.type === 'Effect' && tag.value.verb === 'write') ||
|
|
322
|
-
[
|
|
323
|
-
|
|
328
|
+
[
|
|
329
|
+
ReferenceTag,
|
|
330
|
+
DoctypeTag,
|
|
331
|
+
BindingTag,
|
|
332
|
+
GapTag,
|
|
333
|
+
NullTag,
|
|
334
|
+
InitializerTag,
|
|
335
|
+
ShiftTag,
|
|
336
|
+
AttributeDefinition,
|
|
337
|
+
].includes(tag.type) ||
|
|
338
|
+
(tag.type === OpenNodeTag && (!tag.value.type || ref?.value.type === '@'))
|
|
324
339
|
) {
|
|
325
340
|
state.broken = true;
|
|
326
341
|
|
|
@@ -352,12 +367,7 @@ function* __prettyGroupTags(tags) {
|
|
|
352
367
|
}
|
|
353
368
|
|
|
354
369
|
if (tag.type === OpenNodeTag) {
|
|
355
|
-
|
|
356
|
-
states = states.push({ holding: [], broken: false, open: tag });
|
|
357
|
-
yield tag;
|
|
358
|
-
} else {
|
|
359
|
-
states = states.push({ holding: [tag], broken: false, open: tag });
|
|
360
|
-
}
|
|
370
|
+
states = states.push({ holding: [tag], broken: false, open: tag });
|
|
361
371
|
|
|
362
372
|
state = states.value;
|
|
363
373
|
}
|
|
@@ -393,12 +403,17 @@ function* __generatePrettyCSTML(tags, options) {
|
|
|
393
403
|
continue;
|
|
394
404
|
}
|
|
395
405
|
|
|
406
|
+
if (tag.type === BindingTag && !tag.value.languagePath?.length) {
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
|
|
396
410
|
inline =
|
|
397
411
|
inlineOption &&
|
|
398
412
|
inline &&
|
|
399
413
|
ref &&
|
|
400
414
|
(tag.type === NullTag ||
|
|
401
415
|
tag.type === GapTag ||
|
|
416
|
+
tag.type === BindingTag ||
|
|
402
417
|
tag.type === InitializerTag ||
|
|
403
418
|
tag.type === TokenGroup);
|
|
404
419
|
|
|
@@ -421,7 +436,12 @@ function* __generatePrettyCSTML(tags, options) {
|
|
|
421
436
|
if (tag.type === TokenGroup) {
|
|
422
437
|
ref = null;
|
|
423
438
|
const intrinsicValue = tag.value[0].value.flags.token ? getCooked(tag.value) : null;
|
|
424
|
-
|
|
439
|
+
let openTag = tag.value[0];
|
|
440
|
+
let { flags, type, attributes } = openTag.value;
|
|
441
|
+
yield* printSelfClosingNodeTag(buildOpenNodeTag(flags, type, attributes), intrinsicValue);
|
|
442
|
+
} else if (tag.type === OpenNodeTag) {
|
|
443
|
+
let { flags, type, attributes } = tag.value;
|
|
444
|
+
yield* printTag(buildOpenNodeTag(flags, type, attributes));
|
|
425
445
|
} else {
|
|
426
446
|
yield* printTag(tag);
|
|
427
447
|
}
|
|
@@ -486,11 +506,11 @@ export const getCooked = (tags) => {
|
|
|
486
506
|
}
|
|
487
507
|
}
|
|
488
508
|
|
|
489
|
-
if (!(ref.value.
|
|
509
|
+
if (!(ref.value.type === '#' || (ref.value.type === '@' && attributes.cooked))) {
|
|
490
510
|
throw new Error('cookable nodes must not contain other nodes');
|
|
491
511
|
}
|
|
492
512
|
|
|
493
|
-
if (ref.value.
|
|
513
|
+
if (ref.value.type === '@') {
|
|
494
514
|
const { cooked: cookedValue } = tag.value.attributes;
|
|
495
515
|
|
|
496
516
|
if (!cookedValue) throw new Error('cannot cook string: it contains uncooked escapes');
|
package/lib/symbols.js
CHANGED
|
@@ -4,10 +4,12 @@ export const CloseNodeTag = Symbol.for('CloseNodeTag');
|
|
|
4
4
|
export const ReferenceTag = Symbol.for('ReferenceTag');
|
|
5
5
|
export const ShiftTag = Symbol.for('ShiftTag');
|
|
6
6
|
export const GapTag = Symbol.for('GapTag');
|
|
7
|
+
export const BindingTag = Symbol.for('BindingTag');
|
|
7
8
|
export const NullTag = Symbol.for('NullTag');
|
|
8
9
|
export const InitializerTag = Symbol.for('InitializerTag');
|
|
10
|
+
export const AttributeDefinition = Symbol.for('AttributeDefinition');
|
|
9
11
|
export const LiteralTag = Symbol.for('LiteralTag');
|
|
10
12
|
|
|
11
13
|
export const TokenGroup = Symbol.for('TokenGroup');
|
|
12
14
|
|
|
13
|
-
export const
|
|
15
|
+
export const Property = Symbol.for('Property');
|
package/lib/template.js
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
OpenNodeTag,
|
|
6
6
|
CloseNodeTag,
|
|
7
7
|
DoctypeTag,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Property,
|
|
9
|
+
BindingTag,
|
|
10
10
|
} from './symbols.js';
|
|
11
|
-
import * as
|
|
11
|
+
import * as Children from './children.js';
|
|
12
12
|
import { getOpenTag, get, isFragmentNode } from './tree.js';
|
|
13
13
|
|
|
14
14
|
const { freeze } = Object;
|
|
@@ -21,16 +21,13 @@ export const buildFilledGapFunction = (expressions) => (value) => {
|
|
|
21
21
|
export function* interpolateFragment(node, ref, expressions) {
|
|
22
22
|
const open = getOpenTag(node);
|
|
23
23
|
|
|
24
|
-
if (node.type !== null) throw new Error();
|
|
25
|
-
|
|
26
24
|
const gap = buildFilledGapFunction(expressions);
|
|
27
25
|
|
|
28
|
-
const counters = new Map();
|
|
29
|
-
|
|
30
26
|
if (!open.value.type) {
|
|
31
27
|
let currentRef = null;
|
|
28
|
+
let currentBinding = null;
|
|
32
29
|
let isFragment = isFragmentNode(node);
|
|
33
|
-
for (let tag of
|
|
30
|
+
for (let tag of Children.traverse(node.children)) {
|
|
34
31
|
switch (tag.type) {
|
|
35
32
|
case DoctypeTag: {
|
|
36
33
|
break;
|
|
@@ -48,11 +45,15 @@ export function* interpolateFragment(node, ref, expressions) {
|
|
|
48
45
|
break;
|
|
49
46
|
}
|
|
50
47
|
|
|
48
|
+
case BindingTag: {
|
|
49
|
+
currentBinding = tag;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
|
|
51
53
|
case InitializerTag: {
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
yield freeze({ ...ref });
|
|
54
|
+
const { type } = currentRef.value;
|
|
55
|
+
if (type === '.') {
|
|
56
|
+
yield freeze(ref);
|
|
56
57
|
} else {
|
|
57
58
|
yield currentRef;
|
|
58
59
|
}
|
|
@@ -60,35 +61,21 @@ export function* interpolateFragment(node, ref, expressions) {
|
|
|
60
61
|
break;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
case
|
|
64
|
-
|
|
64
|
+
case Property: {
|
|
65
|
+
let { reference } = tag.value;
|
|
66
|
+
const { type } = reference;
|
|
65
67
|
|
|
66
|
-
if (
|
|
68
|
+
if (type === '.') {
|
|
67
69
|
// TODO check/combine flags
|
|
68
|
-
yield freeze(
|
|
70
|
+
yield freeze(ref);
|
|
71
|
+
yield currentBinding;
|
|
69
72
|
} else {
|
|
70
73
|
yield currentRef;
|
|
74
|
+
yield currentBinding;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
counters.set(name, count);
|
|
76
|
-
|
|
77
|
-
const resolvedRef = t.buildReferenceTag(name, isArray, flags, count);
|
|
77
|
+
yield gap(tag.value.node);
|
|
78
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
79
|
break;
|
|
93
80
|
}
|
|
94
81
|
|
|
@@ -99,8 +86,8 @@ export function* interpolateFragment(node, ref, expressions) {
|
|
|
99
86
|
}
|
|
100
87
|
}
|
|
101
88
|
} else if (open.type === OpenNodeTag) {
|
|
102
|
-
yield freeze(
|
|
103
|
-
yield gap(
|
|
89
|
+
yield freeze(ref);
|
|
90
|
+
yield gap(node);
|
|
104
91
|
} else {
|
|
105
92
|
throw new Error();
|
|
106
93
|
}
|