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