bobe 0.0.36 → 0.0.37

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.
@@ -43,6 +43,23 @@ let NodeSort = function (NodeSort) {
43
43
  TerpEvt["HandledComponentNode"] = "handled-component-node";
44
44
  return TerpEvt;
45
45
  })({});
46
+ let ParseErrorCode = function (ParseErrorCode) {
47
+ ParseErrorCode[ParseErrorCode["UNCLOSED_BRACE"] = 9001] = "UNCLOSED_BRACE";
48
+ ParseErrorCode[ParseErrorCode["UNCLOSED_STRING"] = 9002] = "UNCLOSED_STRING";
49
+ ParseErrorCode[ParseErrorCode["UNCLOSED_STATIC_INS"] = 9003] = "UNCLOSED_STATIC_INS";
50
+ ParseErrorCode[ParseErrorCode["INCONSISTENT_INDENT"] = 9004] = "INCONSISTENT_INDENT";
51
+ ParseErrorCode[ParseErrorCode["INDENT_MISMATCH"] = 9005] = "INDENT_MISMATCH";
52
+ ParseErrorCode[ParseErrorCode["MISSING_ASSIGN"] = 9006] = "MISSING_ASSIGN";
53
+ ParseErrorCode[ParseErrorCode["INVALID_TAG_NAME"] = 9007] = "INVALID_TAG_NAME";
54
+ ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9008] = "ELSE_WITHOUT_IF";
55
+ ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9009] = "EMPTY_IF_BODY";
56
+ ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9010] = "EMPTY_FOR_BODY";
57
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9011] = "MISSING_FOR_COLLECTION";
58
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9012] = "MISSING_FOR_SEMICOLON";
59
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9013] = "MISSING_FOR_ITEM";
60
+ ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9014] = "PIPE_IN_WRONG_CONTEXT";
61
+ return ParseErrorCode;
62
+ }({});
46
63
  class ParseSyntaxError extends SyntaxError {
47
64
  constructor(code, message, loc) {
48
65
  super(message);
@@ -169,7 +186,7 @@ class Tokenizer {
169
186
  const expLen = this.dentStack[i];
170
187
  if (currLen === expLen) break;
171
188
  if (currLen > expLen) {
172
- throw SyntaxError(`缩进错误,缩进长度不匹配`);
189
+ throw new ParseSyntaxError(ParseErrorCode.INCONSISTENT_INDENT, '缩进大小不统一', this.emptyLoc());
173
190
  }
174
191
  if (this.shorterThanBaseDentEof()) {
175
192
  break;
@@ -394,7 +411,7 @@ class Tokenizer {
394
411
  while (1) {
395
412
  nextC = this.code[this.i + 1];
396
413
  if (nextC === undefined) {
397
- this.throwUnclosed('UNCLOSED_STATIC_INS', '未闭合的 "${...}"', startOffset, startLine, startCol);
414
+ this.throwUnclosed(ParseErrorCode.UNCLOSED_STATIC_INS, '未闭合的 "${...}"', startOffset, startLine, startCol);
398
415
  }
399
416
  value += nextC;
400
417
  this.next();
@@ -423,7 +440,7 @@ class Tokenizer {
423
440
  while (1) {
424
441
  const char = this.code[this.i];
425
442
  if (char === undefined) {
426
- this.throwUnclosed('UNCLOSED_BRACE', '未闭合的 "{"', startOffset, startLine, startCol);
443
+ this.throwUnclosed(ParseErrorCode.UNCLOSED_BRACE, '未闭合的 "{"', startOffset, startLine, startCol);
427
444
  }
428
445
  const nextChar = this.code[this.i + 1];
429
446
  if (inComment === 'single' && char === '\n') {
@@ -512,6 +529,18 @@ class Tokenizer {
512
529
  isEmptyLine
513
530
  };
514
531
  }
532
+ emptyLoc() {
533
+ const pos = this.getCurrentPos();
534
+ return {
535
+ start: pos,
536
+ end: {
537
+ offset: pos.offset + 1,
538
+ line: pos.line,
539
+ column: pos.column + 1
540
+ },
541
+ source: ' '
542
+ };
543
+ }
515
544
  dent() {
516
545
  const _this$getDentValue2 = this.getDentValue(),
517
546
  value = _this$getDentValue2.value,
@@ -538,7 +567,7 @@ class Tokenizer {
538
567
  const expLen = this.dentStack[i];
539
568
  if (currLen === expLen) break;
540
569
  if (currLen > expLen) {
541
- throw SyntaxError('缩进大小不统一');
570
+ throw new ParseSyntaxError(ParseErrorCode.INCONSISTENT_INDENT, '缩进大小不统一', this.emptyLoc());
542
571
  }
543
572
  if (this.shorterThanBaseDentEof()) {
544
573
  return;
@@ -616,7 +645,7 @@ class Tokenizer {
616
645
  while (1) {
617
646
  nextC = this.code[this.i + 1];
618
647
  if (nextC === undefined) {
619
- this.throwUnclosed('UNCLOSED_STRING', '未闭合的字符串字面量', startOffset, startLine, startCol);
648
+ this.throwUnclosed(ParseErrorCode.UNCLOSED_STRING, '未闭合的字符串字面量', startOffset, startLine, startCol);
620
649
  }
621
650
  const memoCount = continuousBackslashCount;
622
651
  if (nextC === '\\') {
@@ -937,18 +966,6 @@ class Compiler {
937
966
  loc
938
967
  });
939
968
  }
940
- emptyLoc() {
941
- const pos = this.tokenizer.getCurrentPos();
942
- return {
943
- start: pos,
944
- end: {
945
- offset: pos.offset + 1,
946
- line: pos.line,
947
- column: pos.column + 1
948
- },
949
- source: ' '
950
- };
951
- }
952
969
  parseProgram() {
953
970
  const body = [];
954
971
  try {
@@ -962,10 +979,8 @@ class Compiler {
962
979
  } catch (error) {
963
980
  if (error instanceof ParseSyntaxError) {
964
981
  this.addError(error.code, error.message, error.loc);
965
- } else if (error instanceof SyntaxError) {
966
- const knownCodes = ['INCONSISTENT_INDENT', 'INDENT_MISMATCH'];
967
- const code = knownCodes.includes(error.message) ? error.message : 'INCONSISTENT_INDENT';
968
- this.addError(code, error.message, this.emptyLoc());
982
+ } else {
983
+ this.addError(error.toString(), '未知错误', this.tokenizer.emptyLoc());
969
984
  }
970
985
  }
971
986
  return {
@@ -1005,7 +1020,7 @@ class Compiler {
1005
1020
  templateNode(siblings) {
1006
1021
  const token = this.tokenizer.token;
1007
1022
  if (token.type & TokenType.Pipe) {
1008
- this.addError('PIPE_IN_WRONG_CONTEXT', '"|" 只能出现在元素属性扩展行中', token.loc ?? this.emptyLoc());
1023
+ this.addError(ParseErrorCode.PIPE_IN_WRONG_CONTEXT, '"|" 只能出现在元素属性扩展行中', token.loc ?? this.tokenizer.emptyLoc());
1009
1024
  this.tokenizer.nextToken();
1010
1025
  return null;
1011
1026
  }
@@ -1013,12 +1028,13 @@ class Compiler {
1013
1028
  _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
1014
1029
  hookType = _this$tokenizer$_hook2[0],
1015
1030
  value = _this$tokenizer$_hook2[1];
1016
- if (value === 'if' || value === 'else' || value === 'fail') {
1017
- if (value === 'else' || value === 'fail') {
1031
+ const isElseOrFail = value === 'else' || value === 'fail';
1032
+ if (value === 'if' || isElseOrFail) {
1033
+ if (isElseOrFail) {
1018
1034
  const lastSibling = siblings[siblings.length - 1];
1019
1035
  const lastType = lastSibling?.type;
1020
1036
  if (lastType !== NodeType.If && lastType !== NodeType.Else && lastType !== NodeType.Fail) {
1021
- this.addError('ELSE_WITHOUT_IF', `"${value}" 前必须有 "if" 或 "else" 节点`, token.loc ?? this.emptyLoc());
1037
+ this.addError(ParseErrorCode.ELSE_WITHOUT_IF, `"${value}" 前必须有 "if" 或 "else" 节点`, token.loc ?? this.tokenizer.emptyLoc());
1022
1038
  }
1023
1039
  }
1024
1040
  return this.parseConditionalNode();
@@ -1046,7 +1062,7 @@ class Compiler {
1046
1062
  parseElementNode(node) {
1047
1063
  const tagToken = this.tokenizer.token;
1048
1064
  if (!(tagToken.type & TokenType.Identifier)) {
1049
- this.addError('INVALID_TAG_NAME', `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.emptyLoc());
1065
+ this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc());
1050
1066
  while (!(this.tokenizer.token.type & TokenType.NewLine) && !this.tokenizer.isEof()) {
1051
1067
  this.tokenizer.nextToken();
1052
1068
  }
@@ -1077,15 +1093,15 @@ class Compiler {
1077
1093
  return node;
1078
1094
  }
1079
1095
  parseLoopNode(node) {
1080
- const forLoc = this.tokenizer.token.loc ?? this.emptyLoc();
1096
+ const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
1081
1097
  this.tokenizer.nextToken();
1082
1098
  const collection = this.parsePropertyValue();
1083
1099
  if (!collection.value && collection.value !== 0) {
1084
- this.addError('MISSING_FOR_COLLECTION', '"for" 缺少集合表达式', forLoc);
1100
+ this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc);
1085
1101
  }
1086
1102
  const semicolonToken = this.tokenizer.nextToken();
1087
1103
  if (!(semicolonToken.type & TokenType.Semicolon)) {
1088
- this.addError('MISSING_FOR_SEMICOLON', '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.emptyLoc());
1104
+ this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc());
1089
1105
  }
1090
1106
  const itemToken = this.tokenizer.nextToken();
1091
1107
  const isDestruct = itemToken.type === TokenType.InsertionExp;
@@ -1094,7 +1110,7 @@ class Compiler {
1094
1110
  }
1095
1111
  const item = this.parsePropertyValue();
1096
1112
  if (!item.value && item.value !== 0) {
1097
- this.addError('MISSING_FOR_ITEM', '"for" 缺少 item 变量名', itemToken.loc ?? this.emptyLoc());
1113
+ this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc());
1098
1114
  }
1099
1115
  let char = this.tokenizer.peekChar(),
1100
1116
  key,
@@ -1159,7 +1175,7 @@ class Compiler {
1159
1175
  node.value = this.parsePropertyValue();
1160
1176
  this.tokenizer.nextToken();
1161
1177
  } else {
1162
- this.addError('MISSING_ASSIGN', `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.emptyLoc());
1178
+ this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc());
1163
1179
  }
1164
1180
  node.loc.start = node.key.loc.start;
1165
1181
  node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;