bobe 0.0.73 → 0.0.74

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
@@ -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;
@@ -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 {
@@ -247,12 +249,13 @@ class Tokenizer {
247
249
  if (!this.token) return false;
248
250
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
249
251
  }
250
- setToken(type, value, dt = 1) {
252
+ setToken(type, value, dt = 1, extra) {
251
253
  this.token = {
252
254
  type,
253
255
  typeName: TokenType[type],
254
256
  value,
255
- loc: null
257
+ loc: null,
258
+ ...extra
256
259
  };
257
260
  this.isFirstToken = false;
258
261
  }
@@ -306,6 +309,9 @@ class Tokenizer {
306
309
  const braceToken = this.brace();
307
310
  this.setToken(TokenType.InsertionExp, braceToken);
308
311
  break;
312
+ case '<':
313
+ this.typeArguments();
314
+ break;
309
315
  case '$':
310
316
  const handled = this.staticIns();
311
317
  if (handled) break;
@@ -394,6 +400,104 @@ class Tokenizer {
394
400
  this.locEnd();
395
401
  return this.token;
396
402
  }
403
+ typeArguments() {
404
+ const startOffset = this.i;
405
+ const startLine = this.line;
406
+ const startColumn = this.column;
407
+ let angleDepth = 0;
408
+ let braceDepth = 0;
409
+ let bracketDepth = 0;
410
+ let parenDepth = 0;
411
+ let current = '';
412
+ const args = [];
413
+ let argStart = this.i + 1;
414
+ const makeLoc = (start, end) => ({
415
+ start: {
416
+ offset: start,
417
+ line: startLine,
418
+ column: startColumn + (start - startOffset)
419
+ },
420
+ end: {
421
+ offset: end,
422
+ line: startLine,
423
+ column: startColumn + (end - startOffset)
424
+ },
425
+ source: this.code.slice(start, end)
426
+ });
427
+ const pushArg = end => {
428
+ const raw = current.trim();
429
+ if (!raw) return;
430
+ const leading = current.length - current.trimStart().length;
431
+ const trailingEnd = current.trimEnd().length;
432
+ args.push({
433
+ raw,
434
+ loc: makeLoc(argStart + leading, argStart + trailingEnd)
435
+ });
436
+ };
437
+ while (true) {
438
+ const char = this.code[this.i];
439
+ if (char === undefined || char === '\n') {
440
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
441
+ }
442
+ if (char === '\'' || char === '"' || char === '`') {
443
+ const quote = char;
444
+ current += char;
445
+ this.next();
446
+ while (true) {
447
+ const inner = this.code[this.i];
448
+ if (inner === undefined || inner === '\n') {
449
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
450
+ }
451
+ current += inner;
452
+ if (inner === '\\') {
453
+ this.next();
454
+ current += this.code[this.i] ?? '';
455
+ } else if (inner === quote) {
456
+ break;
457
+ }
458
+ this.next();
459
+ }
460
+ } else if (char === '<') {
461
+ angleDepth++;
462
+ if (angleDepth > 1) current += char;
463
+ } else if (char === '>' && this.code[this.i - 1] !== '=') {
464
+ angleDepth--;
465
+ if (angleDepth === 0) {
466
+ pushArg(this.i);
467
+ this.setToken(TokenType.TypeArguments, this.code.slice(startOffset + 1, this.i), 1, {
468
+ typeArguments: args
469
+ });
470
+ return;
471
+ }
472
+ current += char;
473
+ } else if (char === '{') {
474
+ braceDepth++;
475
+ current += char;
476
+ } else if (char === '}') {
477
+ braceDepth = Math.max(0, braceDepth - 1);
478
+ current += char;
479
+ } else if (char === '[') {
480
+ bracketDepth++;
481
+ current += char;
482
+ } else if (char === ']') {
483
+ bracketDepth = Math.max(0, bracketDepth - 1);
484
+ current += char;
485
+ } else if (char === '(') {
486
+ parenDepth++;
487
+ current += char;
488
+ } else if (char === ')') {
489
+ parenDepth = Math.max(0, parenDepth - 1);
490
+ current += char;
491
+ } else if (char === ',' && angleDepth === 1 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
492
+ pushArg(this.i);
493
+ current = '';
494
+ argStart = this.i + 1;
495
+ } else {
496
+ current += char;
497
+ }
498
+ this.next();
499
+ }
500
+ }
397
501
  peekChar() {
398
502
  let i = this.i;
399
503
  while (this.code[i] === ' ' || this.code[i] === '\t') {
@@ -1105,8 +1209,19 @@ class Compiler {
1105
1209
  parseComponentNode(node) {
1106
1210
  const name = this.parseName();
1107
1211
  this.tokenizer.nextToken();
1212
+ const typeArgumentsToken = this.tokenizer.token.type & TokenType.TypeArguments ? this.tokenizer.token : undefined;
1213
+ if (typeArgumentsToken) {
1214
+ this.tokenizer.nextToken();
1215
+ }
1108
1216
  node.type = NodeType.Component;
1109
1217
  node.componentName = name;
1218
+ node.typeArguments = typeArgumentsToken?.typeArguments?.map(arg => ({
1219
+ type: NodeType.StaticValue,
1220
+ raw: arg.raw,
1221
+ loc: arg.loc
1222
+ }));
1223
+ node.typeArgumentsLoc = typeArgumentsToken?.loc;
1224
+ this.hooks.parseComponentNode?.nameAdded?.call(this, node);
1110
1225
  const props = this.headerLineAndExtensions();
1111
1226
  node.props = props;
1112
1227
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
@@ -1694,6 +1809,7 @@ class Interpreter {
1694
1809
  _node = this.createNode(value);
1695
1810
  }
1696
1811
  this.tokenizer.nextToken();
1812
+ this.skipComponentTypeArguments(_node);
1697
1813
  this.headerLineAndExtensions(_node);
1698
1814
  this.onePropParsed = this.oneRealPropParsed;
1699
1815
  if (_node.__logicType & TokenizerSwitcherBit) {
@@ -1747,6 +1863,7 @@ class Interpreter {
1747
1863
  }, NodeSort.CtxProvider);
1748
1864
  }
1749
1865
  this.tokenizer.nextToken();
1866
+ this.skipComponentTypeArguments(node);
1750
1867
  this.headerLineAndExtensions(node);
1751
1868
  if (isUpdate) {
1752
1869
  this.ctx.stack.pop();
@@ -1776,6 +1893,7 @@ class Interpreter {
1776
1893
  this.handleInsert(node.realParent, textNode, node.realBefore);
1777
1894
  } else {
1778
1895
  this.tokenizer.nextToken();
1896
+ this.skipComponentTypeArguments(node, true);
1779
1897
  this.headerLineAndExtensions(node);
1780
1898
  const _this$ctx2 = this.ctx,
1781
1899
  realParent = _this$ctx2.realParent,
@@ -2511,6 +2629,11 @@ class Interpreter {
2511
2629
  point = next;
2512
2630
  }
2513
2631
  }
2632
+ skipComponentTypeArguments(node, force = false) {
2633
+ if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
2634
+ this.tokenizer.nextToken();
2635
+ }
2636
+ }
2514
2637
  headerLineAndExtensions(_node) {
2515
2638
  const tokenizer = this.tokenizer;
2516
2639
  do {
@@ -2860,5 +2983,5 @@ const effect = (callback, depOrOpt, opt) => {
2860
2983
  return effect$1(callback, option);
2861
2984
  };
2862
2985
 
2863
- export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
2986
+ export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
2864
2987
  //# sourceMappingURL=bobe.esm.js.map