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.
- package/dist/bobe.cjs.js +47 -31
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +47 -31
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +47 -31
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +47 -31
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +19 -4
- package/dist/index.umd.js +47 -31
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -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);
|
|
@@ -160,7 +177,7 @@ class Tokenizer {
|
|
|
160
177
|
const expLen = this.dentStack[i];
|
|
161
178
|
if (currLen === expLen) break;
|
|
162
179
|
if (currLen > expLen) {
|
|
163
|
-
throw
|
|
180
|
+
throw new ParseSyntaxError(ParseErrorCode.INCONSISTENT_INDENT, '缩进大小不统一', this.emptyLoc());
|
|
164
181
|
}
|
|
165
182
|
if (this.shorterThanBaseDentEof()) {
|
|
166
183
|
break;
|
|
@@ -351,7 +368,7 @@ class Tokenizer {
|
|
|
351
368
|
while (1) {
|
|
352
369
|
nextC = this.code[this.i + 1];
|
|
353
370
|
if (nextC === undefined) {
|
|
354
|
-
this.throwUnclosed(
|
|
371
|
+
this.throwUnclosed(ParseErrorCode.UNCLOSED_STATIC_INS, '未闭合的 "${...}"', startOffset, startLine, startCol);
|
|
355
372
|
}
|
|
356
373
|
value += nextC;
|
|
357
374
|
this.next();
|
|
@@ -380,7 +397,7 @@ class Tokenizer {
|
|
|
380
397
|
while (1) {
|
|
381
398
|
const char = this.code[this.i];
|
|
382
399
|
if (char === undefined) {
|
|
383
|
-
this.throwUnclosed(
|
|
400
|
+
this.throwUnclosed(ParseErrorCode.UNCLOSED_BRACE, '未闭合的 "{"', startOffset, startLine, startCol);
|
|
384
401
|
}
|
|
385
402
|
const nextChar = this.code[this.i + 1];
|
|
386
403
|
if (inComment === 'single' && char === '\n') {
|
|
@@ -469,6 +486,18 @@ class Tokenizer {
|
|
|
469
486
|
isEmptyLine
|
|
470
487
|
};
|
|
471
488
|
}
|
|
489
|
+
emptyLoc() {
|
|
490
|
+
const pos = this.getCurrentPos();
|
|
491
|
+
return {
|
|
492
|
+
start: pos,
|
|
493
|
+
end: {
|
|
494
|
+
offset: pos.offset + 1,
|
|
495
|
+
line: pos.line,
|
|
496
|
+
column: pos.column + 1
|
|
497
|
+
},
|
|
498
|
+
source: ' '
|
|
499
|
+
};
|
|
500
|
+
}
|
|
472
501
|
dent() {
|
|
473
502
|
const _this$getDentValue2 = this.getDentValue(),
|
|
474
503
|
value = _this$getDentValue2.value,
|
|
@@ -495,7 +524,7 @@ class Tokenizer {
|
|
|
495
524
|
const expLen = this.dentStack[i];
|
|
496
525
|
if (currLen === expLen) break;
|
|
497
526
|
if (currLen > expLen) {
|
|
498
|
-
throw
|
|
527
|
+
throw new ParseSyntaxError(ParseErrorCode.INCONSISTENT_INDENT, '缩进大小不统一', this.emptyLoc());
|
|
499
528
|
}
|
|
500
529
|
if (this.shorterThanBaseDentEof()) {
|
|
501
530
|
return;
|
|
@@ -573,7 +602,7 @@ class Tokenizer {
|
|
|
573
602
|
while (1) {
|
|
574
603
|
nextC = this.code[this.i + 1];
|
|
575
604
|
if (nextC === undefined) {
|
|
576
|
-
this.throwUnclosed(
|
|
605
|
+
this.throwUnclosed(ParseErrorCode.UNCLOSED_STRING, '未闭合的字符串字面量', startOffset, startLine, startCol);
|
|
577
606
|
}
|
|
578
607
|
const memoCount = continuousBackslashCount;
|
|
579
608
|
if (nextC === '\\') {
|
|
@@ -894,18 +923,6 @@ class Compiler {
|
|
|
894
923
|
loc
|
|
895
924
|
});
|
|
896
925
|
}
|
|
897
|
-
emptyLoc() {
|
|
898
|
-
const pos = this.tokenizer.getCurrentPos();
|
|
899
|
-
return {
|
|
900
|
-
start: pos,
|
|
901
|
-
end: {
|
|
902
|
-
offset: pos.offset + 1,
|
|
903
|
-
line: pos.line,
|
|
904
|
-
column: pos.column + 1
|
|
905
|
-
},
|
|
906
|
-
source: ' '
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
926
|
parseProgram() {
|
|
910
927
|
const body = [];
|
|
911
928
|
try {
|
|
@@ -919,10 +936,8 @@ class Compiler {
|
|
|
919
936
|
} catch (error) {
|
|
920
937
|
if (error instanceof ParseSyntaxError) {
|
|
921
938
|
this.addError(error.code, error.message, error.loc);
|
|
922
|
-
} else
|
|
923
|
-
|
|
924
|
-
const code = knownCodes.includes(error.message) ? error.message : 'INCONSISTENT_INDENT';
|
|
925
|
-
this.addError(code, error.message, this.emptyLoc());
|
|
939
|
+
} else {
|
|
940
|
+
this.addError(error.toString(), '未知错误', this.tokenizer.emptyLoc());
|
|
926
941
|
}
|
|
927
942
|
}
|
|
928
943
|
return {
|
|
@@ -962,7 +977,7 @@ class Compiler {
|
|
|
962
977
|
templateNode(siblings) {
|
|
963
978
|
const token = this.tokenizer.token;
|
|
964
979
|
if (token.type & TokenType.Pipe) {
|
|
965
|
-
this.addError(
|
|
980
|
+
this.addError(ParseErrorCode.PIPE_IN_WRONG_CONTEXT, '"|" 只能出现在元素属性扩展行中', token.loc ?? this.tokenizer.emptyLoc());
|
|
966
981
|
this.tokenizer.nextToken();
|
|
967
982
|
return null;
|
|
968
983
|
}
|
|
@@ -970,12 +985,13 @@ class Compiler {
|
|
|
970
985
|
_this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
|
|
971
986
|
hookType = _this$tokenizer$_hook2[0],
|
|
972
987
|
value = _this$tokenizer$_hook2[1];
|
|
973
|
-
|
|
974
|
-
|
|
988
|
+
const isElseOrFail = value === 'else' || value === 'fail';
|
|
989
|
+
if (value === 'if' || isElseOrFail) {
|
|
990
|
+
if (isElseOrFail) {
|
|
975
991
|
const lastSibling = siblings[siblings.length - 1];
|
|
976
992
|
const lastType = lastSibling?.type;
|
|
977
993
|
if (lastType !== NodeType.If && lastType !== NodeType.Else && lastType !== NodeType.Fail) {
|
|
978
|
-
this.addError(
|
|
994
|
+
this.addError(ParseErrorCode.ELSE_WITHOUT_IF, `"${value}" 前必须有 "if" 或 "else" 节点`, token.loc ?? this.tokenizer.emptyLoc());
|
|
979
995
|
}
|
|
980
996
|
}
|
|
981
997
|
return this.parseConditionalNode();
|
|
@@ -1003,7 +1019,7 @@ class Compiler {
|
|
|
1003
1019
|
parseElementNode(node) {
|
|
1004
1020
|
const tagToken = this.tokenizer.token;
|
|
1005
1021
|
if (!(tagToken.type & TokenType.Identifier)) {
|
|
1006
|
-
this.addError(
|
|
1022
|
+
this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc());
|
|
1007
1023
|
while (!(this.tokenizer.token.type & TokenType.NewLine) && !this.tokenizer.isEof()) {
|
|
1008
1024
|
this.tokenizer.nextToken();
|
|
1009
1025
|
}
|
|
@@ -1034,15 +1050,15 @@ class Compiler {
|
|
|
1034
1050
|
return node;
|
|
1035
1051
|
}
|
|
1036
1052
|
parseLoopNode(node) {
|
|
1037
|
-
const forLoc = this.tokenizer.token.loc ?? this.emptyLoc();
|
|
1053
|
+
const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
|
|
1038
1054
|
this.tokenizer.nextToken();
|
|
1039
1055
|
const collection = this.parsePropertyValue();
|
|
1040
1056
|
if (!collection.value && collection.value !== 0) {
|
|
1041
|
-
this.addError(
|
|
1057
|
+
this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc);
|
|
1042
1058
|
}
|
|
1043
1059
|
const semicolonToken = this.tokenizer.nextToken();
|
|
1044
1060
|
if (!(semicolonToken.type & TokenType.Semicolon)) {
|
|
1045
|
-
this.addError(
|
|
1061
|
+
this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc());
|
|
1046
1062
|
}
|
|
1047
1063
|
const itemToken = this.tokenizer.nextToken();
|
|
1048
1064
|
const isDestruct = itemToken.type === TokenType.InsertionExp;
|
|
@@ -1051,7 +1067,7 @@ class Compiler {
|
|
|
1051
1067
|
}
|
|
1052
1068
|
const item = this.parsePropertyValue();
|
|
1053
1069
|
if (!item.value && item.value !== 0) {
|
|
1054
|
-
this.addError(
|
|
1070
|
+
this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc());
|
|
1055
1071
|
}
|
|
1056
1072
|
let char = this.tokenizer.peekChar(),
|
|
1057
1073
|
key,
|
|
@@ -1116,7 +1132,7 @@ class Compiler {
|
|
|
1116
1132
|
node.value = this.parsePropertyValue();
|
|
1117
1133
|
this.tokenizer.nextToken();
|
|
1118
1134
|
} else {
|
|
1119
|
-
this.addError(
|
|
1135
|
+
this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc());
|
|
1120
1136
|
}
|
|
1121
1137
|
node.loc.start = node.key.loc.start;
|
|
1122
1138
|
node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
|