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.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,
@@ -2512,6 +2630,11 @@ class Interpreter {
2512
2630
  point = next;
2513
2631
  }
2514
2632
  }
2633
+ skipComponentTypeArguments(node, force = false) {
2634
+ if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
2635
+ this.tokenizer.nextToken();
2636
+ }
2637
+ }
2515
2638
  headerLineAndExtensions(_node) {
2516
2639
  const tokenizer = this.tokenizer;
2517
2640
  do {
@@ -2871,6 +2994,7 @@ exports.Interpreter = Interpreter;
2871
2994
  exports.Mw = Mw;
2872
2995
  exports.MwCtx = MwCtx;
2873
2996
  exports.NodeType = NodeType;
2997
+ exports.ParseErrorCode = ParseErrorCode;
2874
2998
  exports.ParseSyntaxError = ParseSyntaxError;
2875
2999
  exports.Tokenizer = Tokenizer;
2876
3000
  exports.bobe = bobe;