bobe 0.0.19 → 0.0.21

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/dist/bobe.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import { getPulling, setPulling, effect, Store, deepSignal, Keys, shareSignal, $, runWithPulling } from 'aoye';
1
+ import { getPulling, setPulling, Keys, $, effect, toRaw, scope, Store, deepSignal, shareSignal, runWithPulling } from 'aoye';
2
2
  export * from 'aoye';
3
- import { BaseEvent, Queue, isNum, matchIdStart } from 'bobe-shared';
3
+ import { BaseEvent, jsVarRegexp, Queue, isNum, matchIdStart2 } from 'bobe-shared';
4
4
 
5
5
  var TokenType = /* @__PURE__ */ ((TokenType2) => {
6
6
  TokenType2[TokenType2["NewLine"] = 1] = "NewLine";
@@ -11,6 +11,7 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
11
11
  TokenType2[TokenType2["Pipe"] = 32] = "Pipe";
12
12
  TokenType2[TokenType2["Eof"] = 64] = "Eof";
13
13
  TokenType2[TokenType2["InsertionExp"] = 128] = "InsertionExp";
14
+ TokenType2[TokenType2["Semicolon"] = 256] = "Semicolon";
14
15
  return TokenType2;
15
16
  })(TokenType || {});
16
17
  var FakeType = /* @__PURE__ */ ((FakeType2) => {
@@ -34,7 +35,6 @@ var NodeSort = /* @__PURE__ */ ((NodeSort2) => {
34
35
  NodeSort2[NodeSort2["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
35
36
  return NodeSort2;
36
37
  })(NodeSort || {});
37
- const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
38
38
 
39
39
  class MultiTypeStack {
40
40
  constructor() {
@@ -129,17 +129,33 @@ class MultiTypeStack {
129
129
  // }
130
130
  }
131
131
 
132
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
133
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
134
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
135
+ var __objRest = (source, exclude) => {
136
+ var target = {};
137
+ for (var prop in source)
138
+ if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
139
+ target[prop] = source[prop];
140
+ if (source != null && __getOwnPropSymbols$1)
141
+ for (var prop of __getOwnPropSymbols$1(source)) {
142
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
143
+ target[prop] = source[prop];
144
+ }
145
+ return target;
146
+ };
132
147
  new BaseEvent();
133
148
  class Interpreter {
134
149
  constructor(tokenizer) {
135
150
  this.tokenizer = tokenizer;
136
151
  this.rootComponent = null;
152
+ this.forItemId = 0;
137
153
  this.oneRealPropParsed = this.onePropParsed.bind(this);
138
154
  }
139
155
  isLogicNode(node) {
140
156
  return node && node.__logicType & LogicalBit;
141
157
  }
142
- program(root, componentNode, before) {
158
+ program(root, componentNode, before, ctxProvider) {
143
159
  var _a, _b;
144
160
  this.rootComponent = componentNode;
145
161
  this.tokenizer.nextToken();
@@ -149,6 +165,12 @@ class Interpreter {
149
165
  { node: componentNode, prev: null },
150
166
  NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher
151
167
  );
168
+ if (ctxProvider) {
169
+ stack.push(
170
+ { node: ctxProvider, prev: null },
171
+ (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider
172
+ );
173
+ }
152
174
  const ctx = this.ctx = {
153
175
  realParent: root,
154
176
  prevSibling: before,
@@ -212,6 +234,21 @@ class Interpreter {
212
234
  const switcher = (_b = stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _b.node;
213
235
  this.tokenizer = switcher.tokenizer;
214
236
  }
237
+ if (parent.__logicType === FakeType.ForItem) {
238
+ const { forNode } = parent;
239
+ const { i, arr, snapshot } = forNode;
240
+ if (i + 1 < arr.length) {
241
+ this.tokenizer.resume(snapshot);
242
+ this.tokenizer.nextToken();
243
+ this.tokenizer.nextToken();
244
+ ctx.prevSibling = parent;
245
+ ctx.current = forNode.children[++forNode.i];
246
+ continue;
247
+ }
248
+ ctx.prevSibling = forNode.prevSibling;
249
+ ctx.current = forNode;
250
+ continue;
251
+ }
215
252
  }
216
253
  ctx.prevSibling = prev;
217
254
  ctx.current = parent;
@@ -222,15 +259,10 @@ class Interpreter {
222
259
  }
223
260
  return componentNode;
224
261
  }
225
- switcherIsRootComponent() {
226
- var _a;
227
- const currentSwitcher = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
228
- return currentSwitcher === this.rootComponent;
229
- }
230
- insertAfterAnchor(ctx) {
231
- const { realParent, prevSibling, stack, before } = ctx;
232
- const afterAnchor = this.createAnchor();
233
- ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
262
+ insertAfterAnchor(name = "anchor") {
263
+ const { realParent, prevSibling, stack, before } = this.ctx;
264
+ const afterAnchor = this.createAnchor(name);
265
+ this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
234
266
  this.handleInsert(realParent, afterAnchor, prevSibling);
235
267
  return afterAnchor;
236
268
  }
@@ -252,7 +284,7 @@ class Interpreter {
252
284
  const childCmp = child;
253
285
  childCmp.realParent = parent;
254
286
  if (prev == null ? void 0 : prev.__logicType) {
255
- childCmp.realBefore = prev.realAfter;
287
+ childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
256
288
  } else {
257
289
  childCmp.realBefore = prev;
258
290
  }
@@ -281,7 +313,10 @@ class Interpreter {
281
313
  let _node;
282
314
  if (value === "if" || value === "else" || value === "fail") {
283
315
  return this.condDeclaration(ctx);
316
+ } else if (value === "for") {
317
+ return this.forDeclaration();
284
318
  } else if (hookType) {
319
+ const data = this.getData();
285
320
  if (hookType === "static") {
286
321
  if (typeof value === "function") {
287
322
  _node = this.componentOrFragmentDeclaration(value, ctx);
@@ -289,7 +324,15 @@ class Interpreter {
289
324
  throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
290
325
  }
291
326
  } else {
292
- _node = this.componentOrFragmentDeclaration(value, ctx);
327
+ const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
328
+ const val = data[Keys.Raw][value];
329
+ if (typeof val === "function") {
330
+ _node = this.componentOrFragmentDeclaration(val, ctx);
331
+ } else {
332
+ const str = valueIsMapKey ? value : this.getFn(data, value);
333
+ _node = this.createNode("text");
334
+ this.onePropParsed(data, _node, "text", str, valueIsMapKey, false);
335
+ }
293
336
  }
294
337
  } else {
295
338
  _node = this.createNode(value);
@@ -303,6 +346,183 @@ class Interpreter {
303
346
  }
304
347
  return _node;
305
348
  }
349
+ forDeclaration() {
350
+ var _a;
351
+ const arrExp = this.tokenizer.nextToken().value;
352
+ this.tokenizer.nextToken();
353
+ const itemToken = this.tokenizer.nextToken();
354
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
355
+ let itemExp = itemToken.value;
356
+ if (isDestruct) {
357
+ itemExp = "{" + itemExp + "}";
358
+ const vars = itemExp.match(jsVarRegexp).join(",");
359
+ itemExp = new Function("item", `let ${vars}; (${itemExp}=item); return {${vars}};`);
360
+ }
361
+ let indexName, keyExp;
362
+ while (this.tokenizer.code[this.tokenizer.i] !== "\n") {
363
+ const next = this.tokenizer.nextToken();
364
+ if (next.type !== TokenType.Semicolon) {
365
+ if (!indexName) {
366
+ indexName = next.value;
367
+ } else {
368
+ keyExp = next.value;
369
+ }
370
+ }
371
+ }
372
+ const owner = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
373
+ const prevSibling = this.ctx.prevSibling;
374
+ const forNode = {
375
+ __logicType: FakeType.For,
376
+ snapshot: this.tokenizer.snapshot(["dentStack", "isFirstToken"]),
377
+ realParent: this.ctx.realParent,
378
+ prevSibling,
379
+ realBefore: (prevSibling == null ? void 0 : prevSibling.realAfter) || prevSibling,
380
+ realAfter: null,
381
+ arr: null,
382
+ itemExp,
383
+ indexName,
384
+ getKey: null,
385
+ children: [],
386
+ effect: null,
387
+ owner,
388
+ i: 0
389
+ };
390
+ if (keyExp) {
391
+ forNode.getKey = new Function("data", `let v;with(data){v=${keyExp}};return v;`);
392
+ }
393
+ window["for1"] = forNode;
394
+ const data = this.getData();
395
+ const cells = data[Keys.Meta].cells;
396
+ const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
397
+ const arrSignal = hasArrExpKey ? (
398
+ // 有 key 直接拿
399
+ (data[arrExp], cells.get(arrExp))
400
+ ) : (
401
+ // 无key
402
+ $(this.getFn(data, arrExp))
403
+ );
404
+ forNode.realAfter = this.insertAfterAnchor("for-after");
405
+ const _b = forNode.snapshot, { dentStack, isFirstToken } = _b, snapshotForUpdate = __objRest(_b, ["dentStack", "isFirstToken"]);
406
+ let isFirstRender = true;
407
+ forNode.effect = effect(() => {
408
+ var _a2;
409
+ let arr = forNode.arr = arrSignal.v;
410
+ arr[Keys.Iterator];
411
+ arr = toRaw(arr);
412
+ const children = forNode.children;
413
+ if (isFirstRender) {
414
+ const len = arr.length;
415
+ for (let i = len; i--; ) {
416
+ const nextItem = children[i + 1];
417
+ const item = this.createForItem(forNode, i, data);
418
+ const anchor = this.insertAfterAnchor("for-item-after");
419
+ item.realAfter = anchor;
420
+ if (nextItem) {
421
+ nextItem.realBefore = anchor;
422
+ }
423
+ item.realParent = forNode.realParent;
424
+ children[i] = item;
425
+ }
426
+ const firstInsert = children[0];
427
+ if (firstInsert) {
428
+ firstInsert.realBefore = forNode.realBefore;
429
+ this.tokenizer.nextToken();
430
+ this.tokenizer.nextToken();
431
+ } else {
432
+ this.tokenizer.skip();
433
+ }
434
+ } else {
435
+ const oldLen = children.length;
436
+ const newLen = arr.length;
437
+ const minLen = Math.min(oldLen, newLen);
438
+ const newChildren = [];
439
+ if (!forNode.getKey) {
440
+ if (newLen < oldLen) {
441
+ for (let i = oldLen - 1; i >= newLen; i--) {
442
+ const child = children[i];
443
+ this.removeLogicNode(child);
444
+ this.remove(child.realAfter);
445
+ child.effect();
446
+ }
447
+ }
448
+ if (oldLen < newLen) {
449
+ const lastAfter = ((_a2 = children.at(-1)) == null ? void 0 : _a2.realAfter) || forNode.realBefore;
450
+ for (let i = newLen - 1; i >= oldLen; i--) {
451
+ const item = this.createForItem(forNode, i, data);
452
+ newChildren[i] = item;
453
+ const nextItem = newChildren[i + 1];
454
+ const anchor = this.createAnchor("for-item-after");
455
+ this.insertAfter(forNode.realParent, anchor, lastAfter);
456
+ item.realAfter = anchor;
457
+ if (nextItem) {
458
+ nextItem.realBefore = anchor;
459
+ }
460
+ item.realParent = forNode.realParent;
461
+ this.tokenizer = owner.tokenizer;
462
+ this.tokenizer.resume(snapshotForUpdate);
463
+ this.tokenizer.useDedentAsEof = false;
464
+ runWithPulling(() => {
465
+ this.program(forNode.realParent, forNode.owner, lastAfter, item);
466
+ }, item.effect.ins);
467
+ }
468
+ const firstInsert = newChildren[oldLen];
469
+ if (firstInsert) {
470
+ firstInsert.realBefore = lastAfter;
471
+ }
472
+ }
473
+ for (let i = minLen; i--; ) {
474
+ const child = children[i];
475
+ newChildren[i] = child;
476
+ if (typeof itemExp === "string") {
477
+ child.data[itemExp] = arr[i];
478
+ } else {
479
+ Object.assign(child.data, itemExp(arr[i]));
480
+ }
481
+ }
482
+ forNode.children = newChildren;
483
+ }
484
+ }
485
+ isFirstRender = false;
486
+ });
487
+ return forNode.children[0] || forNode;
488
+ }
489
+ createForItem(forNode, i, parentData) {
490
+ let forItemNode;
491
+ const effect2 = scope(() => {
492
+ }, null);
493
+ const { arr, itemExp, indexName, getKey } = forNode;
494
+ let data;
495
+ if (typeof itemExp === "string") {
496
+ data = $(
497
+ indexName ? {
498
+ [itemExp]: arr[i],
499
+ [indexName]: i
500
+ } : {
501
+ [itemExp]: arr[i]
502
+ }
503
+ );
504
+ } else {
505
+ const rawData = itemExp(arr[i]);
506
+ if (indexName) {
507
+ rawData[indexName] = i;
508
+ }
509
+ data = $(rawData);
510
+ }
511
+ Object.setPrototypeOf(data, parentData);
512
+ forItemNode = {
513
+ id: this.forItemId++,
514
+ __logicType: FakeType.ForItem,
515
+ realParent: null,
516
+ realBefore: null,
517
+ realAfter: null,
518
+ forNode,
519
+ key: getKey == null ? void 0 : getKey(data),
520
+ effect: null,
521
+ data
522
+ };
523
+ forItemNode.effect = effect2;
524
+ return forItemNode;
525
+ }
306
526
  getData() {
307
527
  const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
308
528
  return node.data || node.owner.data;
@@ -334,10 +554,6 @@ class Interpreter {
334
554
  }
335
555
  componentOrFragmentDeclaration(ComponentOrRender, ctx) {
336
556
  let Component, render, child;
337
- const data = this.getData();
338
- if (typeof ComponentOrRender === "string") {
339
- ComponentOrRender = data[ComponentOrRender];
340
- }
341
557
  const isCC = ComponentOrRender.prototype instanceof Store;
342
558
  if (isCC) {
343
559
  Component = ComponentOrRender;
@@ -351,89 +567,76 @@ class Interpreter {
351
567
  const node = {
352
568
  __logicType: isCC ? FakeType.Component : FakeType.Fragment,
353
569
  realParent: ctx.realParent,
570
+ realBefore: null,
571
+ realAfter: null,
354
572
  data: child,
355
573
  tokenizer: render ? render(true) : child["ui"](true)
356
574
  };
357
- this.onePropParsed = (data2, _, key, value, valueIsMapKey, isFn, hookI) => {
575
+ this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
358
576
  if (isFn) {
359
577
  child[Keys.Raw][key] = value;
360
578
  } else if (valueIsMapKey) {
361
- shareSignal(data2, value, child, key);
362
- } else if (typeof value === "function") {
579
+ shareSignal(data, value, child, key);
580
+ } else {
363
581
  const meta = child[Keys.Meta];
364
582
  const cells = meta.cells;
365
- const computed = $(value);
366
- cells.set(key, computed);
367
- child[Keys.Raw][key] = void 0;
368
- } else {
369
- child[Keys.Raw][key] = value;
583
+ if (typeof value === "function") {
584
+ const computed = $(value);
585
+ cells.set(key, computed);
586
+ child[Keys.Raw][key] = void 0;
587
+ } else {
588
+ cells.set(key, { v: value });
589
+ child[Keys.Raw][key] = value;
590
+ }
370
591
  }
371
592
  };
372
- node.realAfter = this.insertAfterAnchor(ctx);
593
+ node.realAfter = this.insertAfterAnchor("component-after");
373
594
  return node;
374
595
  }
596
+ getFn(data, expression) {
597
+ return new Function("data", `let v;with(data){v=${expression}};return v;`).bind(void 0, data);
598
+ }
375
599
  // TODO: 优化代码逻辑,拆分 if elseif else
376
600
  condDeclaration(ctx) {
377
601
  var _a;
378
602
  const { prevSibling } = ctx;
379
- const snapbackUp = this.tokenizer.snapshot();
380
603
  const keyWord = this.tokenizer.token;
381
- this.tokenizer.nextToken();
382
- const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
383
- const [hookType, value] = this.tokenizer._hook({});
604
+ const expToken = this.tokenizer.condExp();
605
+ const value = expToken.value;
384
606
  const isElse = keyWord.value === "else";
385
607
  const isIf = keyWord.value === "if";
386
608
  const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
387
- const needCalcWithPrevIf = isElse && preIsCond;
388
609
  const data = this.getData();
610
+ const noCond = value === true;
611
+ const valueIsMapKey = !noCond && Reflect.has(data[Keys.Raw], value);
389
612
  const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
390
613
  const ifNode = {
391
614
  __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
392
- snapshot: noSelfCond ? snapbackUp : this.tokenizer.snapshot(),
393
- condition: null,
615
+ // 此时 token exp, 下次解析 从 \n 开始
616
+ snapshot: this.tokenizer.snapshot(),
394
617
  realParent: null,
618
+ realBefore: null,
619
+ realAfter: null,
620
+ condition: null,
395
621
  preCond: preIsCond ? prevSibling : null,
396
622
  isFirstRender: true,
397
623
  effect: null,
398
624
  owner
399
625
  };
400
626
  let signal;
401
- if (noSelfCond) {
402
- if (isElse) {
403
- signal = $(() => {
404
- let point = ifNode.preCond;
405
- while (point) {
406
- if (point.condition.v) {
407
- return false;
408
- }
409
- if (point.__logicType === FakeType.If) {
410
- break;
411
- }
412
- point = point.preCond;
413
- }
414
- return true;
415
- });
416
- } else {
417
- signal = $(() => {
418
- let point = ifNode.preCond;
419
- while (point) {
420
- if (point.condition.v) {
421
- return false;
422
- }
423
- point = point.preCond;
424
- }
425
- return true;
426
- });
427
- }
428
- } else {
429
- const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
430
- if (valueIsMapKey && !needCalcWithPrevIf) {
431
- runWithPulling(() => data[value], null);
432
- const { cells } = data[Keys.Meta];
433
- signal = cells.get(value);
434
- } else {
435
- const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
436
- if (needCalcWithPrevIf) {
627
+ switch (keyWord.value) {
628
+ case "if":
629
+ if (valueIsMapKey) {
630
+ runWithPulling(() => data[value], null);
631
+ const { cells } = data[Keys.Meta];
632
+ signal = cells.get(value);
633
+ } else {
634
+ const fn = this.getFn(data, value);
635
+ signal = $(fn);
636
+ }
637
+ break;
638
+ case "else":
639
+ if (noCond) {
437
640
  signal = $(() => {
438
641
  let point = ifNode.preCond;
439
642
  while (point) {
@@ -445,43 +648,57 @@ class Interpreter {
445
648
  }
446
649
  point = point.preCond;
447
650
  }
448
- return fn();
651
+ return true;
449
652
  });
450
653
  } else {
451
- signal = $(fn);
654
+ const fn = valueIsMapKey ? null : this.getFn(data, value);
655
+ signal = $(() => {
656
+ let point = ifNode.preCond;
657
+ while (point) {
658
+ if (point.condition.v) {
659
+ return false;
660
+ }
661
+ if (point.__logicType === FakeType.If) {
662
+ break;
663
+ }
664
+ point = point.preCond;
665
+ }
666
+ return valueIsMapKey ? data[value] : fn();
667
+ });
452
668
  }
453
- }
669
+ break;
670
+ case "fail":
671
+ signal = $(() => {
672
+ let point = ifNode.preCond;
673
+ while (point) {
674
+ if (point.condition.v) {
675
+ return false;
676
+ }
677
+ point = point.preCond;
678
+ }
679
+ return true;
680
+ });
681
+ break;
454
682
  }
455
683
  ifNode.condition = signal;
456
- ifNode.realAfter = this.insertAfterAnchor(ctx);
684
+ ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
457
685
  ifNode.effect = effect(
458
686
  ({ val }) => {
459
687
  if (val) {
460
688
  if (ifNode.isFirstRender) {
461
- if (!noSelfCond) {
462
- this.tokenizer.nextToken();
463
- }
689
+ this.tokenizer.nextToken();
464
690
  this.tokenizer.nextToken();
465
691
  } else {
466
692
  this.tokenizer = ifNode.owner.tokenizer;
467
693
  this.tokenizer.resume(ifNode.snapshot);
468
- this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore);
694
+ this.tokenizer.useDedentAsEof = false;
695
+ this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
469
696
  }
470
697
  } else {
471
698
  if (ifNode.isFirstRender) {
472
- if (noSelfCond) {
473
- this.tokenizer.i = this.tokenizer.i - 1;
474
- this.tokenizer.needIndent = false;
475
- }
476
699
  this.tokenizer.skip();
477
700
  } else {
478
- const { realBefore, realAfter, realParent } = ifNode;
479
- let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
480
- while (point !== realAfter) {
481
- const next = this.nextSib(point);
482
- this.remove(point, realParent, realBefore);
483
- point = next;
484
- }
701
+ this.removeLogicNode(ifNode);
485
702
  }
486
703
  }
487
704
  ifNode.isFirstRender = false;
@@ -490,6 +707,15 @@ class Interpreter {
490
707
  );
491
708
  return ifNode;
492
709
  }
710
+ removeLogicNode(node) {
711
+ const { realBefore, realAfter, realParent } = node;
712
+ let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
713
+ while (point !== realAfter) {
714
+ const next = this.nextSib(point);
715
+ this.remove(point, realParent, realBefore);
716
+ point = next;
717
+ }
718
+ }
493
719
  /**
494
720
  * <extensionLines> ::= PIPE <attributeList> NEWLINE <extensionLines>
495
721
  * | ε
@@ -540,7 +766,7 @@ class Interpreter {
540
766
  const isFn = typeof rawVal === "function";
541
767
  if (hookType === "dynamic") {
542
768
  const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
543
- const fn = isFn ? rawVal : valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
769
+ const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
544
770
  this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
545
771
  } else if (hookType === "static") {
546
772
  this.onePropParsed(data, _node, key, value, false, isFn, hookI);
@@ -570,14 +796,9 @@ class Interpreter {
570
796
  firstChild(node) {
571
797
  return node.firstChild;
572
798
  }
573
- _createAnchor() {
574
- const anchor = this.createAnchor();
575
- anchor[IsAnchor] = true;
576
- return anchor;
577
- }
578
- createAnchor() {
799
+ createAnchor(name) {
579
800
  return {
580
- name: "anchor",
801
+ name,
581
802
  nextSibling: null
582
803
  };
583
804
  }
@@ -633,9 +854,9 @@ var __spreadValues = (a, b) => {
633
854
  };
634
855
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
635
856
  const _Tokenizer = class _Tokenizer {
636
- constructor(hook, isSubToken) {
857
+ constructor(hook, useDedentAsEof) {
637
858
  this.hook = hook;
638
- this.isSubToken = isSubToken;
859
+ this.useDedentAsEof = useDedentAsEof;
639
860
  /** 缩进大小 默认 2 */
640
861
  this.TabSize = 2;
641
862
  /** 缩进字符 */
@@ -680,7 +901,7 @@ const _Tokenizer = class _Tokenizer {
680
901
  }
681
902
  return [hookType, value];
682
903
  };
683
- if (isSubToken) {
904
+ if (useDedentAsEof) {
684
905
  this.setToken(TokenType.Indent, "");
685
906
  this.isFirstToken = true;
686
907
  }
@@ -698,11 +919,20 @@ const _Tokenizer = class _Tokenizer {
698
919
  this.dentStack = [0];
699
920
  Object.assign(this, _snapshot);
700
921
  }
701
- snapshot() {
702
- return {
922
+ snapshot(keys) {
923
+ const snap = {
703
924
  i: this.i,
704
925
  waitingTokens: this.waitingTokens.clone()
705
926
  };
927
+ if (keys) {
928
+ for (const k of keys) {
929
+ snap[k] = this[k];
930
+ if (k === "dentStack") {
931
+ snap[k] = this[k].slice();
932
+ }
933
+ }
934
+ }
935
+ return snap;
706
936
  }
707
937
  skip() {
708
938
  const logicDentLen = this.dentStack[this.dentStack.length - 1];
@@ -816,17 +1046,21 @@ ${_Tokenizer.EofId}`;
816
1046
  this.str(char);
817
1047
  break;
818
1048
  case "{":
819
- this.brace();
1049
+ const braceToken = this.brace();
1050
+ this.setToken(TokenType.InsertionExp, braceToken);
820
1051
  break;
821
1052
  case "$":
822
1053
  const handled = this.dynamic(char);
823
1054
  if (handled) break;
1055
+ case ";":
1056
+ this.setToken(TokenType.Semicolon, ";");
1057
+ break;
824
1058
  default:
825
1059
  if (isNum(char)) {
826
1060
  this.number(char);
827
1061
  break;
828
1062
  }
829
- if (typeof char === "string" && matchIdStart(char)) {
1063
+ if (typeof char === "string" && matchIdStart2(char, 0)) {
830
1064
  this.identifier(char);
831
1065
  }
832
1066
  break;
@@ -845,6 +1079,58 @@ ${_Tokenizer.EofId}`;
845
1079
  this.handledTokens.push(this.token);
846
1080
  }
847
1081
  }
1082
+ condExp() {
1083
+ let value = "";
1084
+ this.token = null;
1085
+ while (1) {
1086
+ const char = this.code[this.i];
1087
+ if (char === "\n") {
1088
+ break;
1089
+ }
1090
+ value += char;
1091
+ this.i++;
1092
+ }
1093
+ value = value.trim();
1094
+ this.setToken(TokenType.Identifier, value || true);
1095
+ return this.token;
1096
+ }
1097
+ /**
1098
+ * 解析到 for 时使用这个方法获取 for 后方的子表达式
1099
+ * 表达式通过 “;” 分割
1100
+ * // 最多可有三个表达式
1101
+ * for arr ; item index; item.key
1102
+ * @returns {boolean} 是否含有 key
1103
+ */
1104
+ forLoopSubExp() {
1105
+ this.token = null;
1106
+ let value = "";
1107
+ let count = 0;
1108
+ while (1) {
1109
+ const char = this.code[this.i];
1110
+ const isSemicolon = char === ";";
1111
+ if (isSemicolon || char === "\n") {
1112
+ value = value.trim();
1113
+ if (!this.token) {
1114
+ this.setToken(TokenType.Identifier, value);
1115
+ } else {
1116
+ this.waitingTokens.push({
1117
+ type: TokenType.Identifier,
1118
+ typeName: TokenType[TokenType.Identifier],
1119
+ value
1120
+ });
1121
+ }
1122
+ value = "";
1123
+ count++;
1124
+ if (count > 3) {
1125
+ throw SyntaxError(`for \u5FAA\u73AF\u6700\u591A\u53EF\u5305\u542B\u4E09\u4E2A\u8868\u8FBE\u5F0F, \u5206\u522B\u4E3A arr ; item index [; key]`);
1126
+ }
1127
+ if (!isSemicolon) return count === 3;
1128
+ } else {
1129
+ value += char;
1130
+ }
1131
+ this.i++;
1132
+ }
1133
+ }
848
1134
  assignment() {
849
1135
  this.setToken(TokenType.Assign, "=");
850
1136
  }
@@ -910,8 +1196,7 @@ ${_Tokenizer.EofId}`;
910
1196
  }
911
1197
  }
912
1198
  if (count === 0 && inString == null && inComment == null) {
913
- this.setToken(TokenType.InsertionExp, value.slice(1));
914
- return;
1199
+ return value.slice(1);
915
1200
  }
916
1201
  value += this.code[this.i];
917
1202
  this.i++;
@@ -1016,13 +1301,13 @@ ${_Tokenizer.EofId}`;
1016
1301
  const yes = this.dentStack.length === 1;
1017
1302
  if (yes) {
1018
1303
  if (!this.token) {
1019
- if (this.isSubToken) {
1304
+ if (this.useDedentAsEof) {
1020
1305
  this.setToken(TokenType.Dedent, "");
1021
1306
  } else {
1022
1307
  this.setToken(TokenType.Identifier, _Tokenizer.EofId);
1023
1308
  }
1024
1309
  } else {
1025
- if (this.isSubToken) {
1310
+ if (this.useDedentAsEof) {
1026
1311
  this.waitingTokens.push({
1027
1312
  type: TokenType.Dedent,
1028
1313
  typeName: TokenType[TokenType.Dedent],
@@ -1044,13 +1329,13 @@ ${_Tokenizer.EofId}`;
1044
1329
  let nextC;
1045
1330
  while (1) {
1046
1331
  nextC = this.code[this.i + 1];
1047
- if (typeof nextC !== "string" || !matchIdStart(nextC)) {
1332
+ if (typeof nextC !== "string" || !matchIdStart2(nextC, 0)) {
1048
1333
  break;
1049
1334
  }
1050
1335
  value += nextC;
1051
1336
  this.i++;
1052
1337
  }
1053
- if (value === _Tokenizer.EofId && this.isSubToken) {
1338
+ if (value === _Tokenizer.EofId && this.useDedentAsEof) {
1054
1339
  this.setToken(TokenType.Dedent, "");
1055
1340
  return;
1056
1341
  }