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/index.d.ts CHANGED
@@ -73,6 +73,7 @@ declare class Interpreter {
73
73
  getAssignFn(data: any, expression: string | number): any;
74
74
  condDeclaration(ctx: ProgramCtx): IfNode;
75
75
  removeLogicNode(node: LogicNode): void;
76
+ private skipComponentTypeArguments;
76
77
  /**
77
78
  * 首行属性 + 可选的 pipe 扩展行
78
79
  * <headerLineAndExtensions> ::= <attributeList> NEWLINE (PIPE <attributeList> NEWLINE)*
@@ -178,7 +179,8 @@ declare enum TokenType {
178
179
  Boolean = 4096,
179
180
  Null = 8192,
180
181
  Undefined = 16384,
181
- Comment = 32768
182
+ Comment = 32768,
183
+ TypeArguments = 65536
182
184
  }
183
185
  declare enum FakeType {
184
186
  If = 1,
@@ -209,6 +211,10 @@ type Token = {
209
211
  typeName: string;
210
212
  value: BaseType;
211
213
  loc: SourceLocation;
214
+ typeArguments?: {
215
+ raw: string;
216
+ loc: SourceLocation;
217
+ }[];
212
218
  };
213
219
  type HookProps = {
214
220
  /** 通过哪个 HookId 进入的 */
@@ -247,7 +253,8 @@ declare enum ParseErrorCode {
247
253
  MISSING_FOR_ITEM = 9014,
248
254
  MISSING_COMMENT_SECOND_SLASH = 9015,
249
255
  MISSING_PROP_ASSIGNMENT = 9016,
250
- PIPE_IN_WRONG_CONTEXT = 9017
256
+ PIPE_IN_WRONG_CONTEXT = 9017,
257
+ UNCLOSED_TYPE_ARGUMENTS = 9018
251
258
  }
252
259
  type ParseError = {
253
260
  code: ParseErrorCode;
@@ -434,6 +441,7 @@ declare class Tokenizer {
434
441
  * @returns {boolean} 是否含有 key
435
442
  */
436
443
  jsExp(): Token;
444
+ private typeArguments;
437
445
  peekChar(): string;
438
446
  peekCharIsEol(): boolean;
439
447
  charIsEol(char: string): char is "/" | "\n";
@@ -538,9 +546,15 @@ interface LoopNode extends BaseNode {
538
546
  key?: PropertyValue;
539
547
  children: TemplateNode[];
540
548
  }
549
+ interface TypeArgumentNode extends BaseNode {
550
+ type: NodeType.StaticValue;
551
+ raw: string;
552
+ }
541
553
  interface ComponentNode extends BaseNode {
542
554
  type: NodeType.Component;
543
555
  componentName: PropertyValue;
556
+ typeArguments?: TypeArgumentNode[];
557
+ typeArgumentsLoc?: SourceLocation;
544
558
  props: Property[];
545
559
  children?: TemplateNode[];
546
560
  }
@@ -618,6 +632,7 @@ type ParseHooks = Partial<{
618
632
  [K in keyof ParseProps]: {
619
633
  enter?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
620
634
  leave?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
635
+ nameAdded?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
621
636
  propsAdded?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
622
637
  };
623
638
  }>;
@@ -631,4 +646,4 @@ declare const context: IContext;
631
646
  declare const effect: (callback: (...args: ValueDiff[]) => void, depOrOpt?: Dep[] | Dep | CustomEffectOpt, opt?: CustomEffectOpt) => aoye.Effect;
632
647
 
633
648
  export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
634
- export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, IContext, InterpolationNode, LogicNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode, UI };
649
+ export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, IContext, InterpolationNode, LogicNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode, TypeArgumentNode, UI };
package/dist/index.umd.js CHANGED
@@ -21,6 +21,7 @@
21
21
  TokenType[TokenType["Null"] = 8192] = "Null";
22
22
  TokenType[TokenType["Undefined"] = 16384] = "Undefined";
23
23
  TokenType[TokenType["Comment"] = 32768] = "Comment";
24
+ TokenType[TokenType["TypeArguments"] = 65536] = "TypeArguments";
24
25
  return TokenType;
25
26
  }({});
26
27
  const ChildrenSugarType = TokenType.String | TokenType.InsertionExp;
@@ -76,6 +77,7 @@
76
77
  ParseErrorCode[ParseErrorCode["MISSING_COMMENT_SECOND_SLASH"] = 9015] = "MISSING_COMMENT_SECOND_SLASH";
77
78
  ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9016] = "MISSING_PROP_ASSIGNMENT";
78
79
  ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9017] = "PIPE_IN_WRONG_CONTEXT";
80
+ ParseErrorCode[ParseErrorCode["UNCLOSED_TYPE_ARGUMENTS"] = 9018] = "UNCLOSED_TYPE_ARGUMENTS";
79
81
  return ParseErrorCode;
80
82
  }({});
81
83
  class ParseSyntaxError extends SyntaxError {
@@ -249,12 +251,13 @@
249
251
  if (!this.token) return false;
250
252
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
251
253
  }
252
- setToken(type, value, dt = 1) {
254
+ setToken(type, value, dt = 1, extra) {
253
255
  this.token = {
254
256
  type,
255
257
  typeName: TokenType[type],
256
258
  value,
257
- loc: null
259
+ loc: null,
260
+ ...extra
258
261
  };
259
262
  this.isFirstToken = false;
260
263
  }
@@ -308,6 +311,9 @@
308
311
  const braceToken = this.brace();
309
312
  this.setToken(TokenType.InsertionExp, braceToken);
310
313
  break;
314
+ case '<':
315
+ this.typeArguments();
316
+ break;
311
317
  case '$':
312
318
  const handled = this.staticIns();
313
319
  if (handled) break;
@@ -396,6 +402,104 @@
396
402
  this.locEnd();
397
403
  return this.token;
398
404
  }
405
+ typeArguments() {
406
+ const startOffset = this.i;
407
+ const startLine = this.line;
408
+ const startColumn = this.column;
409
+ let angleDepth = 0;
410
+ let braceDepth = 0;
411
+ let bracketDepth = 0;
412
+ let parenDepth = 0;
413
+ let current = '';
414
+ const args = [];
415
+ let argStart = this.i + 1;
416
+ const makeLoc = (start, end) => ({
417
+ start: {
418
+ offset: start,
419
+ line: startLine,
420
+ column: startColumn + (start - startOffset)
421
+ },
422
+ end: {
423
+ offset: end,
424
+ line: startLine,
425
+ column: startColumn + (end - startOffset)
426
+ },
427
+ source: this.code.slice(start, end)
428
+ });
429
+ const pushArg = end => {
430
+ const raw = current.trim();
431
+ if (!raw) return;
432
+ const leading = current.length - current.trimStart().length;
433
+ const trailingEnd = current.trimEnd().length;
434
+ args.push({
435
+ raw,
436
+ loc: makeLoc(argStart + leading, argStart + trailingEnd)
437
+ });
438
+ };
439
+ while (true) {
440
+ const char = this.code[this.i];
441
+ if (char === undefined || char === '\n') {
442
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
443
+ }
444
+ if (char === '\'' || char === '"' || char === '`') {
445
+ const quote = char;
446
+ current += char;
447
+ this.next();
448
+ while (true) {
449
+ const inner = this.code[this.i];
450
+ if (inner === undefined || inner === '\n') {
451
+ throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
452
+ }
453
+ current += inner;
454
+ if (inner === '\\') {
455
+ this.next();
456
+ current += this.code[this.i] ?? '';
457
+ } else if (inner === quote) {
458
+ break;
459
+ }
460
+ this.next();
461
+ }
462
+ } else if (char === '<') {
463
+ angleDepth++;
464
+ if (angleDepth > 1) current += char;
465
+ } else if (char === '>' && this.code[this.i - 1] !== '=') {
466
+ angleDepth--;
467
+ if (angleDepth === 0) {
468
+ pushArg(this.i);
469
+ this.setToken(TokenType.TypeArguments, this.code.slice(startOffset + 1, this.i), 1, {
470
+ typeArguments: args
471
+ });
472
+ return;
473
+ }
474
+ current += char;
475
+ } else if (char === '{') {
476
+ braceDepth++;
477
+ current += char;
478
+ } else if (char === '}') {
479
+ braceDepth = Math.max(0, braceDepth - 1);
480
+ current += char;
481
+ } else if (char === '[') {
482
+ bracketDepth++;
483
+ current += char;
484
+ } else if (char === ']') {
485
+ bracketDepth = Math.max(0, bracketDepth - 1);
486
+ current += char;
487
+ } else if (char === '(') {
488
+ parenDepth++;
489
+ current += char;
490
+ } else if (char === ')') {
491
+ parenDepth = Math.max(0, parenDepth - 1);
492
+ current += char;
493
+ } else if (char === ',' && angleDepth === 1 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
494
+ pushArg(this.i);
495
+ current = '';
496
+ argStart = this.i + 1;
497
+ } else {
498
+ current += char;
499
+ }
500
+ this.next();
501
+ }
502
+ }
399
503
  peekChar() {
400
504
  let i = this.i;
401
505
  while (this.code[i] === ' ' || this.code[i] === '\t') {
@@ -1107,8 +1211,19 @@
1107
1211
  parseComponentNode(node) {
1108
1212
  const name = this.parseName();
1109
1213
  this.tokenizer.nextToken();
1214
+ const typeArgumentsToken = this.tokenizer.token.type & TokenType.TypeArguments ? this.tokenizer.token : undefined;
1215
+ if (typeArgumentsToken) {
1216
+ this.tokenizer.nextToken();
1217
+ }
1110
1218
  node.type = NodeType.Component;
1111
1219
  node.componentName = name;
1220
+ node.typeArguments = typeArgumentsToken?.typeArguments?.map(arg => ({
1221
+ type: NodeType.StaticValue,
1222
+ raw: arg.raw,
1223
+ loc: arg.loc
1224
+ }));
1225
+ node.typeArgumentsLoc = typeArgumentsToken?.loc;
1226
+ this.hooks.parseComponentNode?.nameAdded?.call(this, node);
1112
1227
  const props = this.headerLineAndExtensions();
1113
1228
  node.props = props;
1114
1229
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
@@ -1696,6 +1811,7 @@
1696
1811
  _node = this.createNode(value);
1697
1812
  }
1698
1813
  this.tokenizer.nextToken();
1814
+ this.skipComponentTypeArguments(_node);
1699
1815
  this.headerLineAndExtensions(_node);
1700
1816
  this.onePropParsed = this.oneRealPropParsed;
1701
1817
  if (_node.__logicType & TokenizerSwitcherBit) {
@@ -1749,6 +1865,7 @@
1749
1865
  }, NodeSort.CtxProvider);
1750
1866
  }
1751
1867
  this.tokenizer.nextToken();
1868
+ this.skipComponentTypeArguments(node);
1752
1869
  this.headerLineAndExtensions(node);
1753
1870
  if (isUpdate) {
1754
1871
  this.ctx.stack.pop();
@@ -1778,6 +1895,7 @@
1778
1895
  this.handleInsert(node.realParent, textNode, node.realBefore);
1779
1896
  } else {
1780
1897
  this.tokenizer.nextToken();
1898
+ this.skipComponentTypeArguments(node, true);
1781
1899
  this.headerLineAndExtensions(node);
1782
1900
  const _this$ctx2 = this.ctx,
1783
1901
  realParent = _this$ctx2.realParent,
@@ -2513,6 +2631,11 @@
2513
2631
  point = next;
2514
2632
  }
2515
2633
  }
2634
+ skipComponentTypeArguments(node, force = false) {
2635
+ if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
2636
+ this.tokenizer.nextToken();
2637
+ }
2638
+ }
2516
2639
  headerLineAndExtensions(_node) {
2517
2640
  const tokenizer = this.tokenizer;
2518
2641
  do {
@@ -2872,6 +2995,7 @@
2872
2995
  exports.Mw = Mw;
2873
2996
  exports.MwCtx = MwCtx;
2874
2997
  exports.NodeType = NodeType;
2998
+ exports.ParseErrorCode = ParseErrorCode;
2875
2999
  exports.ParseSyntaxError = ParseSyntaxError;
2876
3000
  exports.Tokenizer = Tokenizer;
2877
3001
  exports.bobe = bobe;