bobe 0.0.73 → 0.0.75

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.cjs CHANGED
@@ -20,6 +20,7 @@ let TokenType = function (TokenType) {
20
20
  TokenType[TokenType["Null"] = 8192] = "Null";
21
21
  TokenType[TokenType["Undefined"] = 16384] = "Undefined";
22
22
  TokenType[TokenType["Comment"] = 32768] = "Comment";
23
+ TokenType[TokenType["TypeArguments"] = 65536] = "TypeArguments";
23
24
  return TokenType;
24
25
  }({});
25
26
  const ChildrenSugarType = TokenType.String | TokenType.InsertionExp;
@@ -75,6 +76,7 @@ let ParseErrorCode = function (ParseErrorCode) {
75
76
  ParseErrorCode[ParseErrorCode["MISSING_COMMENT_SECOND_SLASH"] = 9015] = "MISSING_COMMENT_SECOND_SLASH";
76
77
  ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9016] = "MISSING_PROP_ASSIGNMENT";
77
78
  ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9017] = "PIPE_IN_WRONG_CONTEXT";
79
+ ParseErrorCode[ParseErrorCode["UNCLOSED_TYPE_ARGUMENTS"] = 9018] = "UNCLOSED_TYPE_ARGUMENTS";
78
80
  return ParseErrorCode;
79
81
  }({});
80
82
  class ParseSyntaxError extends SyntaxError {
@@ -248,12 +250,13 @@ class Tokenizer {
248
250
  if (!this.token) return false;
249
251
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
250
252
  }
251
- setToken(type, value, dt = 1) {
253
+ setToken(type, value, dt = 1, extra) {
252
254
  this.token = {
253
255
  type,
254
256
  typeName: TokenType[type],
255
257
  value,
256
- loc: null
258
+ loc: null,
259
+ ...extra
257
260
  };
258
261
  this.isFirstToken = false;
259
262
  }
@@ -307,6 +310,9 @@ class Tokenizer {
307
310
  const braceToken = this.brace();
308
311
  this.setToken(TokenType.InsertionExp, braceToken);
309
312
  break;
313
+ case '<':
314
+ this.typeArguments();
315
+ break;
310
316
  case '$':
311
317
  const handled = this.staticIns();
312
318
  if (handled) break;
@@ -395,6 +401,104 @@ class Tokenizer {
395
401
  this.locEnd();
396
402
  return this.token;
397
403
  }
404
+ typeArguments() {
405
+ const startOffset = this.i;
406
+ const startLine = this.line;
407
+ const startColumn = this.column;
408
+ let angleDepth = 0;
409
+ let braceDepth = 0;
410
+ let bracketDepth = 0;
411
+ let parenDepth = 0;
412
+ let current = '';
413
+ const args = [];
414
+ let argStart = this.i + 1;
415
+ const makeLoc = (start, end) => ({
416
+ start: {
417
+ offset: start,
418
+ line: startLine,
419
+ column: startColumn + (start - startOffset)
420
+ },
421
+ end: {
422
+ offset: end,
423
+ line: startLine,
424
+ column: startColumn + (end - startOffset)
425
+ },
426
+ source: this.code.slice(start, end)
427
+ });
428
+ const pushArg = end => {
429
+ const raw = current.trim();
430
+ if (!raw) return;
431
+ const leading = current.length - current.trimStart().length;
432
+ const trailingEnd = current.trimEnd().length;
433
+ args.push({
434
+ raw,
435
+ loc: makeLoc(argStart + leading, argStart + trailingEnd)
436
+ });
437
+ };
438
+ while (true) {
439
+ const char = this.code[this.i];
440
+ if (char === undefined || char === '\n') {
441
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
442
+ }
443
+ if (char === '\'' || char === '"' || char === '`') {
444
+ const quote = char;
445
+ current += char;
446
+ this.next();
447
+ while (true) {
448
+ const inner = this.code[this.i];
449
+ if (inner === undefined || inner === '\n') {
450
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
451
+ }
452
+ current += inner;
453
+ if (inner === '\\') {
454
+ this.next();
455
+ current += this.code[this.i] ?? '';
456
+ } else if (inner === quote) {
457
+ break;
458
+ }
459
+ this.next();
460
+ }
461
+ } else if (char === '<') {
462
+ angleDepth++;
463
+ if (angleDepth > 1) current += char;
464
+ } else if (char === '>' && this.code[this.i - 1] !== '=') {
465
+ angleDepth--;
466
+ if (angleDepth === 0) {
467
+ pushArg(this.i);
468
+ this.setToken(TokenType.TypeArguments, this.code.slice(startOffset + 1, this.i), 1, {
469
+ typeArguments: args
470
+ });
471
+ return;
472
+ }
473
+ current += char;
474
+ } else if (char === '{') {
475
+ braceDepth++;
476
+ current += char;
477
+ } else if (char === '}') {
478
+ braceDepth = Math.max(0, braceDepth - 1);
479
+ current += char;
480
+ } else if (char === '[') {
481
+ bracketDepth++;
482
+ current += char;
483
+ } else if (char === ']') {
484
+ bracketDepth = Math.max(0, bracketDepth - 1);
485
+ current += char;
486
+ } else if (char === '(') {
487
+ parenDepth++;
488
+ current += char;
489
+ } else if (char === ')') {
490
+ parenDepth = Math.max(0, parenDepth - 1);
491
+ current += char;
492
+ } else if (char === ',' && angleDepth === 1 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
493
+ pushArg(this.i);
494
+ current = '';
495
+ argStart = this.i + 1;
496
+ } else {
497
+ current += char;
498
+ }
499
+ this.next();
500
+ }
501
+ }
398
502
  peekChar() {
399
503
  let i = this.i;
400
504
  while (this.code[i] === ' ' || this.code[i] === '\t') {
@@ -1106,8 +1210,19 @@ class Compiler {
1106
1210
  parseComponentNode(node) {
1107
1211
  const name = this.parseName();
1108
1212
  this.tokenizer.nextToken();
1213
+ const typeArgumentsToken = this.tokenizer.token.type & TokenType.TypeArguments ? this.tokenizer.token : undefined;
1214
+ if (typeArgumentsToken) {
1215
+ this.tokenizer.nextToken();
1216
+ }
1109
1217
  node.type = NodeType.Component;
1110
1218
  node.componentName = name;
1219
+ node.typeArguments = typeArgumentsToken?.typeArguments?.map(arg => ({
1220
+ type: NodeType.StaticValue,
1221
+ raw: arg.raw,
1222
+ loc: arg.loc
1223
+ }));
1224
+ node.typeArgumentsLoc = typeArgumentsToken?.loc;
1225
+ this.hooks.parseComponentNode?.nameAdded?.call(this, node);
1111
1226
  const props = this.headerLineAndExtensions();
1112
1227
  node.props = props;
1113
1228
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
@@ -1695,6 +1810,7 @@ class Interpreter {
1695
1810
  _node = this.createNode(value);
1696
1811
  }
1697
1812
  this.tokenizer.nextToken();
1813
+ this.skipComponentTypeArguments(_node);
1698
1814
  this.headerLineAndExtensions(_node);
1699
1815
  this.onePropParsed = this.oneRealPropParsed;
1700
1816
  if (_node.__logicType & TokenizerSwitcherBit) {
@@ -1748,6 +1864,7 @@ class Interpreter {
1748
1864
  }, NodeSort.CtxProvider);
1749
1865
  }
1750
1866
  this.tokenizer.nextToken();
1867
+ this.skipComponentTypeArguments(node);
1751
1868
  this.headerLineAndExtensions(node);
1752
1869
  if (isUpdate) {
1753
1870
  this.ctx.stack.pop();
@@ -1777,6 +1894,7 @@ class Interpreter {
1777
1894
  this.handleInsert(node.realParent, textNode, node.realBefore);
1778
1895
  } else {
1779
1896
  this.tokenizer.nextToken();
1897
+ this.skipComponentTypeArguments(node, true);
1780
1898
  this.headerLineAndExtensions(node);
1781
1899
  const _this$ctx2 = this.ctx,
1782
1900
  realParent = _this$ctx2.realParent,
@@ -2382,6 +2500,11 @@ class Interpreter {
2382
2500
  getFn(data, expression) {
2383
2501
  return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2384
2502
  }
2503
+ getBoolFn(data, expression) {
2504
+ return new Function('data', `with(data){return Boolean(${expression})}`).bind(undefined, safeExclude(data, {
2505
+ 'Boolean': true
2506
+ }));
2507
+ }
2385
2508
  getAssignFn(data, expression) {
2386
2509
  const valueId = `value_bobe_${bobeShared.date32()}`;
2387
2510
  return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, safeExclude(data, {
@@ -2419,11 +2542,9 @@ class Interpreter {
2419
2542
  switch (keyWord.value) {
2420
2543
  case 'if':
2421
2544
  if (valueIsMapKey) {
2422
- aoye.runWithPulling(() => data[value], null);
2423
- const cells = data[aoye.Keys.Meta].cells;
2424
- signal = cells.get(value);
2545
+ signal = new aoye.Computed(() => Boolean(data[value]));
2425
2546
  } else {
2426
- const fn = this.getFn(data, value);
2547
+ const fn = this.getBoolFn(data, value);
2427
2548
  signal = new aoye.Computed(fn);
2428
2549
  }
2429
2550
  break;
@@ -2443,7 +2564,7 @@ class Interpreter {
2443
2564
  return true;
2444
2565
  });
2445
2566
  } else {
2446
- const fn = valueIsMapKey ? null : this.getFn(data, value);
2567
+ const fn = valueIsMapKey ? null : this.getBoolFn(data, value);
2447
2568
  signal = new aoye.Computed(() => {
2448
2569
  let point = ifNode.preCond;
2449
2570
  while (point) {
@@ -2455,7 +2576,7 @@ class Interpreter {
2455
2576
  }
2456
2577
  point = point.preCond;
2457
2578
  }
2458
- return valueIsMapKey ? data[value] : fn();
2579
+ return valueIsMapKey ? Boolean(data[value]) : fn();
2459
2580
  });
2460
2581
  }
2461
2582
  break;
@@ -2512,6 +2633,11 @@ class Interpreter {
2512
2633
  point = next;
2513
2634
  }
2514
2635
  }
2636
+ skipComponentTypeArguments(node, force = false) {
2637
+ if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
2638
+ this.tokenizer.nextToken();
2639
+ }
2640
+ }
2515
2641
  headerLineAndExtensions(_node) {
2516
2642
  const tokenizer = this.tokenizer;
2517
2643
  do {
@@ -2871,6 +2997,7 @@ exports.Interpreter = Interpreter;
2871
2997
  exports.Mw = Mw;
2872
2998
  exports.MwCtx = MwCtx;
2873
2999
  exports.NodeType = NodeType;
3000
+ exports.ParseErrorCode = ParseErrorCode;
2874
3001
  exports.ParseSyntaxError = ParseSyntaxError;
2875
3002
  exports.Tokenizer = Tokenizer;
2876
3003
  exports.bobe = bobe;