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.
@@ -19,6 +19,7 @@ let TokenType = function (TokenType) {
19
19
  TokenType[TokenType["Null"] = 8192] = "Null";
20
20
  TokenType[TokenType["Undefined"] = 16384] = "Undefined";
21
21
  TokenType[TokenType["Comment"] = 32768] = "Comment";
22
+ TokenType[TokenType["TypeArguments"] = 65536] = "TypeArguments";
22
23
  return TokenType;
23
24
  }({});
24
25
  const ChildrenSugarType = TokenType.String | TokenType.InsertionExp | TokenType.StaticInsExp ;
@@ -74,6 +75,7 @@ let ParseErrorCode = function (ParseErrorCode) {
74
75
  ParseErrorCode[ParseErrorCode["MISSING_COMMENT_SECOND_SLASH"] = 9015] = "MISSING_COMMENT_SECOND_SLASH";
75
76
  ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9016] = "MISSING_PROP_ASSIGNMENT";
76
77
  ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9017] = "PIPE_IN_WRONG_CONTEXT";
78
+ ParseErrorCode[ParseErrorCode["UNCLOSED_TYPE_ARGUMENTS"] = 9018] = "UNCLOSED_TYPE_ARGUMENTS";
77
79
  return ParseErrorCode;
78
80
  }({});
79
81
  class ParseSyntaxError extends SyntaxError {
@@ -256,7 +258,7 @@ class Tokenizer {
256
258
  if (!this.token) return false;
257
259
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
258
260
  }
259
- setToken(type, value, dt = 1) {
261
+ setToken(type, value, dt = 1, extra) {
260
262
  this.token = {
261
263
  type,
262
264
  typeName: TokenType[type],
@@ -273,7 +275,8 @@ class Tokenizer {
273
275
  column: this.column + dt
274
276
  },
275
277
  source: this.code.slice(this.preI, this.i + dt)
276
- } : null
278
+ } : null,
279
+ ...extra
277
280
  };
278
281
  this.isFirstToken = false;
279
282
  }
@@ -327,6 +330,9 @@ class Tokenizer {
327
330
  const braceToken = this.brace();
328
331
  this.setToken(TokenType.InsertionExp, braceToken);
329
332
  break;
333
+ case '<':
334
+ this.typeArguments();
335
+ break;
330
336
  case '$':
331
337
  const handled = this.staticIns();
332
338
  if (handled) break;
@@ -423,6 +429,104 @@ class Tokenizer {
423
429
  this.locEnd();
424
430
  return this.token;
425
431
  }
432
+ typeArguments() {
433
+ const startOffset = this.i;
434
+ const startLine = this.line;
435
+ const startColumn = this.column;
436
+ let angleDepth = 0;
437
+ let braceDepth = 0;
438
+ let bracketDepth = 0;
439
+ let parenDepth = 0;
440
+ let current = '';
441
+ const args = [];
442
+ let argStart = this.i + 1;
443
+ const makeLoc = (start, end) => ({
444
+ start: {
445
+ offset: start,
446
+ line: startLine,
447
+ column: startColumn + (start - startOffset)
448
+ },
449
+ end: {
450
+ offset: end,
451
+ line: startLine,
452
+ column: startColumn + (end - startOffset)
453
+ },
454
+ source: this.code.slice(start, end)
455
+ });
456
+ const pushArg = end => {
457
+ const raw = current.trim();
458
+ if (!raw) return;
459
+ const leading = current.length - current.trimStart().length;
460
+ const trailingEnd = current.trimEnd().length;
461
+ args.push({
462
+ raw,
463
+ loc: makeLoc(argStart + leading, argStart + trailingEnd)
464
+ });
465
+ };
466
+ while (true) {
467
+ const char = this.code[this.i];
468
+ if (char === undefined || char === '\n') {
469
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
470
+ }
471
+ if (char === '\'' || char === '"' || char === '`') {
472
+ const quote = char;
473
+ current += char;
474
+ this.next();
475
+ while (true) {
476
+ const inner = this.code[this.i];
477
+ if (inner === undefined || inner === '\n') {
478
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
479
+ }
480
+ current += inner;
481
+ if (inner === '\\') {
482
+ this.next();
483
+ current += this.code[this.i] ?? '';
484
+ } else if (inner === quote) {
485
+ break;
486
+ }
487
+ this.next();
488
+ }
489
+ } else if (char === '<') {
490
+ angleDepth++;
491
+ if (angleDepth > 1) current += char;
492
+ } else if (char === '>' && this.code[this.i - 1] !== '=') {
493
+ angleDepth--;
494
+ if (angleDepth === 0) {
495
+ pushArg(this.i);
496
+ this.setToken(TokenType.TypeArguments, this.code.slice(startOffset + 1, this.i), 1, {
497
+ typeArguments: args
498
+ });
499
+ return;
500
+ }
501
+ current += char;
502
+ } else if (char === '{') {
503
+ braceDepth++;
504
+ current += char;
505
+ } else if (char === '}') {
506
+ braceDepth = Math.max(0, braceDepth - 1);
507
+ current += char;
508
+ } else if (char === '[') {
509
+ bracketDepth++;
510
+ current += char;
511
+ } else if (char === ']') {
512
+ bracketDepth = Math.max(0, bracketDepth - 1);
513
+ current += char;
514
+ } else if (char === '(') {
515
+ parenDepth++;
516
+ current += char;
517
+ } else if (char === ')') {
518
+ parenDepth = Math.max(0, parenDepth - 1);
519
+ current += char;
520
+ } else if (char === ',' && angleDepth === 1 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
521
+ pushArg(this.i);
522
+ current = '';
523
+ argStart = this.i + 1;
524
+ } else {
525
+ current += char;
526
+ }
527
+ this.next();
528
+ }
529
+ }
426
530
  peekChar() {
427
531
  let i = this.i;
428
532
  while (this.code[i] === ' ' || this.code[i] === '\t') {
@@ -1132,8 +1236,19 @@ class Compiler {
1132
1236
  parseComponentNode(node) {
1133
1237
  const name = this.parseName();
1134
1238
  this.tokenizer.nextToken();
1239
+ const typeArgumentsToken = this.tokenizer.token.type & TokenType.TypeArguments ? this.tokenizer.token : undefined;
1240
+ if (typeArgumentsToken) {
1241
+ this.tokenizer.nextToken();
1242
+ }
1135
1243
  node.type = NodeType.Component;
1136
1244
  node.componentName = name;
1245
+ node.typeArguments = typeArgumentsToken?.typeArguments?.map(arg => ({
1246
+ type: NodeType.StaticValue,
1247
+ raw: arg.raw,
1248
+ loc: arg.loc
1249
+ }));
1250
+ node.typeArgumentsLoc = typeArgumentsToken?.loc;
1251
+ this.hooks.parseComponentNode?.nameAdded?.call(this, node);
1137
1252
  const props = this.headerLineAndExtensions();
1138
1253
  node.props = props;
1139
1254
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
@@ -1721,6 +1836,7 @@ class Interpreter {
1721
1836
  _node = this.createNode(value);
1722
1837
  }
1723
1838
  this.tokenizer.nextToken();
1839
+ this.skipComponentTypeArguments(_node);
1724
1840
  this.headerLineAndExtensions(_node);
1725
1841
  this.onePropParsed = this.oneRealPropParsed;
1726
1842
  if (_node.__logicType & TokenizerSwitcherBit) {
@@ -1774,6 +1890,7 @@ class Interpreter {
1774
1890
  }, NodeSort.CtxProvider);
1775
1891
  }
1776
1892
  this.tokenizer.nextToken();
1893
+ this.skipComponentTypeArguments(node);
1777
1894
  this.headerLineAndExtensions(node);
1778
1895
  if (isUpdate) {
1779
1896
  this.ctx.stack.pop();
@@ -1803,6 +1920,7 @@ class Interpreter {
1803
1920
  this.handleInsert(node.realParent, textNode, node.realBefore);
1804
1921
  } else {
1805
1922
  this.tokenizer.nextToken();
1923
+ this.skipComponentTypeArguments(node, true);
1806
1924
  this.headerLineAndExtensions(node);
1807
1925
  const _this$ctx2 = this.ctx,
1808
1926
  realParent = _this$ctx2.realParent,
@@ -2408,6 +2526,11 @@ class Interpreter {
2408
2526
  getFn(data, expression) {
2409
2527
  return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2410
2528
  }
2529
+ getBoolFn(data, expression) {
2530
+ return new Function('data', `with(data){return Boolean(${expression})}`).bind(undefined, safeExclude(data, {
2531
+ 'Boolean': true
2532
+ }));
2533
+ }
2411
2534
  getAssignFn(data, expression) {
2412
2535
  const valueId = `value_bobe_${date32()}`;
2413
2536
  return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, safeExclude(data, {
@@ -2445,11 +2568,9 @@ class Interpreter {
2445
2568
  switch (keyWord.value) {
2446
2569
  case 'if':
2447
2570
  if (valueIsMapKey) {
2448
- runWithPulling(() => data[value], null);
2449
- const cells = data[Keys.Meta].cells;
2450
- signal = cells.get(value);
2571
+ signal = new Computed(() => Boolean(data[value]));
2451
2572
  } else {
2452
- const fn = this.getFn(data, value);
2573
+ const fn = this.getBoolFn(data, value);
2453
2574
  signal = new Computed(fn);
2454
2575
  }
2455
2576
  break;
@@ -2469,7 +2590,7 @@ class Interpreter {
2469
2590
  return true;
2470
2591
  });
2471
2592
  } else {
2472
- const fn = valueIsMapKey ? null : this.getFn(data, value);
2593
+ const fn = valueIsMapKey ? null : this.getBoolFn(data, value);
2473
2594
  signal = new Computed(() => {
2474
2595
  let point = ifNode.preCond;
2475
2596
  while (point) {
@@ -2481,7 +2602,7 @@ class Interpreter {
2481
2602
  }
2482
2603
  point = point.preCond;
2483
2604
  }
2484
- return valueIsMapKey ? data[value] : fn();
2605
+ return valueIsMapKey ? Boolean(data[value]) : fn();
2485
2606
  });
2486
2607
  }
2487
2608
  break;
@@ -2538,6 +2659,11 @@ class Interpreter {
2538
2659
  point = next;
2539
2660
  }
2540
2661
  }
2662
+ skipComponentTypeArguments(node, force = false) {
2663
+ if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
2664
+ this.tokenizer.nextToken();
2665
+ }
2666
+ }
2541
2667
  headerLineAndExtensions(_node) {
2542
2668
  const tokenizer = this.tokenizer;
2543
2669
  do {
@@ -2887,5 +3013,5 @@ const effect = (callback, depOrOpt, opt) => {
2887
3013
  return effect$1(callback, option);
2888
3014
  };
2889
3015
 
2890
- export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
3016
+ export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
2891
3017
  //# sourceMappingURL=bobe.compiler.esm.js.map