bobe 0.0.16 → 0.0.17
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 +81 -92
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +82 -93
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +2 -19
- package/dist/index.umd.js +81 -92
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -109,30 +109,34 @@ class MultiTypeStack {
|
|
|
109
109
|
var _a;
|
|
110
110
|
return (_a = this.top) == null ? void 0 : _a.value;
|
|
111
111
|
}
|
|
112
|
-
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
forEach(callback) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
112
|
+
// /**
|
|
113
|
+
// * 1. 全局向前遍历 (不分类)
|
|
114
|
+
// * 从栈顶开始,沿着全局链条向栈底遍历
|
|
115
|
+
// */
|
|
116
|
+
// forEach(callback: (value: T, types: number) => any): void {
|
|
117
|
+
// let current = this.top;
|
|
118
|
+
// while (current !== null) {
|
|
119
|
+
// // 执行回调,如果返回 false 则立即停止
|
|
120
|
+
// const shouldBreak = callback(current.value, current.types);
|
|
121
|
+
// if (shouldBreak) break;
|
|
122
|
+
// current = current.prevGlobal;
|
|
123
|
+
// }
|
|
124
|
+
// }
|
|
125
|
+
// /**
|
|
126
|
+
// * 2. 按类别向前遍历
|
|
127
|
+
// * 仅遍历属于指定类别 cat 的节点
|
|
128
|
+
// */
|
|
129
|
+
// forEachByType(cat: number, callback: (value: T) => any): void {
|
|
130
|
+
// // 从该类别的当前“顶端”节点开始
|
|
131
|
+
// let current = this.typeTops[cat];
|
|
132
|
+
// while (current) {
|
|
133
|
+
// const shouldBreak = callback(current.value);
|
|
134
|
+
// if (shouldBreak) break;
|
|
135
|
+
// // 关键点:直接跳向该节点记录的“上一个同类节点”
|
|
136
|
+
// // 这比遍历全局栈再筛选类别要快得多 (O(m) vs O(n))
|
|
137
|
+
// current = current.prevByType[cat];
|
|
138
|
+
// }
|
|
139
|
+
// }
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
const tap = new bobeShared.BaseEvent();
|
|
@@ -147,7 +151,7 @@ class Interpreter {
|
|
|
147
151
|
program(root, componentNode, before) {
|
|
148
152
|
var _a, _b;
|
|
149
153
|
this.rootComponent = componentNode;
|
|
150
|
-
this.tokenizer.
|
|
154
|
+
this.tokenizer.nextToken();
|
|
151
155
|
const stack = new MultiTypeStack();
|
|
152
156
|
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
153
157
|
stack.push(
|
|
@@ -170,7 +174,7 @@ class Interpreter {
|
|
|
170
174
|
}
|
|
171
175
|
const token = this.tokenizer.token;
|
|
172
176
|
if (token.type & TokenType.Indent) {
|
|
173
|
-
this.tokenizer.
|
|
177
|
+
this.tokenizer.nextToken();
|
|
174
178
|
const isLogicNode = this.isLogicNode(ctx.current);
|
|
175
179
|
stack.push(
|
|
176
180
|
{
|
|
@@ -199,7 +203,7 @@ class Interpreter {
|
|
|
199
203
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
200
204
|
}
|
|
201
205
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
202
|
-
this.tokenizer.
|
|
206
|
+
this.tokenizer.nextToken();
|
|
203
207
|
const [{ node: parent, prev }, sort] = stack.pop();
|
|
204
208
|
if (!parent.__logicType) {
|
|
205
209
|
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
@@ -304,7 +308,7 @@ class Interpreter {
|
|
|
304
308
|
} else {
|
|
305
309
|
_node = this.createNode(value);
|
|
306
310
|
}
|
|
307
|
-
this.tokenizer.
|
|
311
|
+
this.tokenizer.nextToken();
|
|
308
312
|
this.headerLine(_node);
|
|
309
313
|
this.extensionLines(_node);
|
|
310
314
|
if (_node.__logicType === FakeType.Component) {
|
|
@@ -393,7 +397,8 @@ class Interpreter {
|
|
|
393
397
|
var _a;
|
|
394
398
|
const { prevSibling } = ctx;
|
|
395
399
|
const snapbackUp = this.tokenizer.snapshot();
|
|
396
|
-
const keyWord = this.tokenizer.
|
|
400
|
+
const keyWord = this.tokenizer.token;
|
|
401
|
+
this.tokenizer.nextToken();
|
|
397
402
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
398
403
|
const [hookType, value] = this.tokenizer._hook({});
|
|
399
404
|
const isElse = keyWord.value === "else";
|
|
@@ -474,9 +479,9 @@ class Interpreter {
|
|
|
474
479
|
if (val) {
|
|
475
480
|
if (ifNode.isFirstRender) {
|
|
476
481
|
if (!noSelfCond) {
|
|
477
|
-
this.tokenizer.
|
|
482
|
+
this.tokenizer.nextToken();
|
|
478
483
|
}
|
|
479
|
-
this.tokenizer.
|
|
484
|
+
this.tokenizer.nextToken();
|
|
480
485
|
} else {
|
|
481
486
|
this.tokenizer = ifNode.owner.tokenizer;
|
|
482
487
|
this.tokenizer.resume(ifNode.snapshot);
|
|
@@ -511,15 +516,15 @@ class Interpreter {
|
|
|
511
516
|
*/
|
|
512
517
|
extensionLines(_node) {
|
|
513
518
|
while (1) {
|
|
514
|
-
if (
|
|
519
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
515
520
|
return;
|
|
516
521
|
}
|
|
517
|
-
this.tokenizer.
|
|
522
|
+
this.tokenizer.nextToken();
|
|
518
523
|
this.attributeList(_node);
|
|
519
|
-
if (
|
|
524
|
+
if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
520
525
|
return;
|
|
521
526
|
}
|
|
522
|
-
this.tokenizer.
|
|
527
|
+
this.tokenizer.nextToken();
|
|
523
528
|
}
|
|
524
529
|
}
|
|
525
530
|
/**
|
|
@@ -529,7 +534,7 @@ class Interpreter {
|
|
|
529
534
|
*/
|
|
530
535
|
headerLine(_node) {
|
|
531
536
|
this.attributeList(_node);
|
|
532
|
-
this.tokenizer.
|
|
537
|
+
this.tokenizer.nextToken();
|
|
533
538
|
}
|
|
534
539
|
/**
|
|
535
540
|
* 属性列表:
|
|
@@ -539,19 +544,19 @@ class Interpreter {
|
|
|
539
544
|
*
|
|
540
545
|
* <attribute> ::= <key> = <value>
|
|
541
546
|
* 1. 普通节点 执行 setProps 🪝
|
|
542
|
-
* 2. 组件节点
|
|
547
|
+
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
543
548
|
*/
|
|
544
549
|
attributeList(_node) {
|
|
545
550
|
let key, eq;
|
|
546
551
|
const data = this.getData();
|
|
547
|
-
while (
|
|
552
|
+
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
548
553
|
if (key == null) {
|
|
549
554
|
key = this.tokenizer.token.value;
|
|
550
555
|
} else if (eq == null) {
|
|
551
556
|
eq = "=";
|
|
552
557
|
} else {
|
|
553
558
|
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
554
|
-
const rawVal =
|
|
559
|
+
const rawVal = data[aoye.Keys.Raw][value];
|
|
555
560
|
const isFn = typeof rawVal === "function";
|
|
556
561
|
if (hookType === "dynamic") {
|
|
557
562
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
@@ -565,7 +570,7 @@ class Interpreter {
|
|
|
565
570
|
key = null;
|
|
566
571
|
eq = null;
|
|
567
572
|
}
|
|
568
|
-
this.tokenizer.
|
|
573
|
+
this.tokenizer.nextToken();
|
|
569
574
|
}
|
|
570
575
|
}
|
|
571
576
|
config(opt) {
|
|
@@ -725,16 +730,16 @@ const _Tokenizer = class _Tokenizer {
|
|
|
725
730
|
let skipFragment = ``;
|
|
726
731
|
this.token = void 0;
|
|
727
732
|
while (1) {
|
|
728
|
-
const char = this.
|
|
733
|
+
const char = this.code[this.i];
|
|
729
734
|
if (char === "\n") {
|
|
730
735
|
needIndent = true;
|
|
731
736
|
skipFragment += char;
|
|
732
|
-
this.
|
|
737
|
+
this.i++;
|
|
733
738
|
continue;
|
|
734
739
|
}
|
|
735
740
|
if (!needIndent) {
|
|
736
741
|
skipFragment += char;
|
|
737
|
-
this.
|
|
742
|
+
this.i++;
|
|
738
743
|
continue;
|
|
739
744
|
}
|
|
740
745
|
needIndent = false;
|
|
@@ -787,21 +792,6 @@ ${_Tokenizer.EofId}`;
|
|
|
787
792
|
if (!this.token) return false;
|
|
788
793
|
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
789
794
|
}
|
|
790
|
-
get char() {
|
|
791
|
-
return this.code[this.i];
|
|
792
|
-
}
|
|
793
|
-
get prev() {
|
|
794
|
-
return this.code[this.i - 1];
|
|
795
|
-
}
|
|
796
|
-
get after() {
|
|
797
|
-
return this.code[this.i + 1];
|
|
798
|
-
}
|
|
799
|
-
next() {
|
|
800
|
-
const prev = this.code[this.i];
|
|
801
|
-
this.i++;
|
|
802
|
-
const curr = this.code[this.i];
|
|
803
|
-
return [prev, curr];
|
|
804
|
-
}
|
|
805
795
|
setToken(type, value) {
|
|
806
796
|
this.token = {
|
|
807
797
|
type,
|
|
@@ -810,10 +800,6 @@ ${_Tokenizer.EofId}`;
|
|
|
810
800
|
};
|
|
811
801
|
this.isFirstToken = false;
|
|
812
802
|
}
|
|
813
|
-
testId(value) {
|
|
814
|
-
if (typeof value !== "string") return false;
|
|
815
|
-
return _Tokenizer.IdExp.test(value);
|
|
816
|
-
}
|
|
817
803
|
nextToken() {
|
|
818
804
|
try {
|
|
819
805
|
if (this.isEof()) {
|
|
@@ -829,7 +815,7 @@ ${_Tokenizer.EofId}`;
|
|
|
829
815
|
if (this.needIndent) {
|
|
830
816
|
this.dent();
|
|
831
817
|
} else {
|
|
832
|
-
|
|
818
|
+
const char = this.code[this.i];
|
|
833
819
|
switch (char) {
|
|
834
820
|
case " ":
|
|
835
821
|
case " ":
|
|
@@ -860,12 +846,12 @@ ${_Tokenizer.EofId}`;
|
|
|
860
846
|
this.number(char);
|
|
861
847
|
break;
|
|
862
848
|
}
|
|
863
|
-
if (
|
|
849
|
+
if (typeof char === "string" && bobeShared.matchIdStart(char)) {
|
|
864
850
|
this.identifier(char);
|
|
865
851
|
}
|
|
866
852
|
break;
|
|
867
853
|
}
|
|
868
|
-
this.
|
|
854
|
+
this.i++;
|
|
869
855
|
}
|
|
870
856
|
if (this.token) {
|
|
871
857
|
break;
|
|
@@ -874,6 +860,7 @@ ${_Tokenizer.EofId}`;
|
|
|
874
860
|
return this.token;
|
|
875
861
|
} catch (error) {
|
|
876
862
|
console.error(error);
|
|
863
|
+
return this.token;
|
|
877
864
|
} finally {
|
|
878
865
|
this.handledTokens.push(this.token);
|
|
879
866
|
}
|
|
@@ -885,17 +872,17 @@ ${_Tokenizer.EofId}`;
|
|
|
885
872
|
this.setToken(TokenType.Pipe, "|");
|
|
886
873
|
}
|
|
887
874
|
dynamic(char) {
|
|
888
|
-
let nextC = this.
|
|
875
|
+
let nextC = this.code[this.i + 1];
|
|
889
876
|
if (nextC !== "{") {
|
|
890
877
|
return false;
|
|
891
878
|
}
|
|
892
|
-
this.
|
|
879
|
+
this.i++;
|
|
893
880
|
let value = "${";
|
|
894
881
|
let innerBrace = 0;
|
|
895
882
|
while (1) {
|
|
896
|
-
nextC = this.
|
|
883
|
+
nextC = this.code[this.i + 1];
|
|
897
884
|
value += nextC;
|
|
898
|
-
this.
|
|
885
|
+
this.i++;
|
|
899
886
|
if (nextC === "{") {
|
|
900
887
|
innerBrace++;
|
|
901
888
|
}
|
|
@@ -912,13 +899,14 @@ ${_Tokenizer.EofId}`;
|
|
|
912
899
|
brace() {
|
|
913
900
|
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
914
901
|
while (1) {
|
|
915
|
-
const char = this.
|
|
916
|
-
const nextChar = this.
|
|
902
|
+
const char = this.code[this.i];
|
|
903
|
+
const nextChar = this.code[this.i + 1];
|
|
917
904
|
if (inComment === "single" && char === "\n") {
|
|
918
905
|
inComment = null;
|
|
919
906
|
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
920
907
|
inComment = null;
|
|
921
|
-
value += this.
|
|
908
|
+
value += this.code[this.i];
|
|
909
|
+
this.i++;
|
|
922
910
|
} else if (inString) {
|
|
923
911
|
if (char === inString && backslashCount % 2 === 0) {
|
|
924
912
|
inString = null;
|
|
@@ -927,10 +915,12 @@ ${_Tokenizer.EofId}`;
|
|
|
927
915
|
} else {
|
|
928
916
|
if (char === "/" && nextChar === "/") {
|
|
929
917
|
inComment = "single";
|
|
930
|
-
value += this.
|
|
918
|
+
value += this.code[this.i];
|
|
919
|
+
this.i++;
|
|
931
920
|
} else if (char === "/" && nextChar === "*") {
|
|
932
921
|
inComment = "multi";
|
|
933
|
-
value += this.
|
|
922
|
+
value += this.code[this.i];
|
|
923
|
+
this.i++;
|
|
934
924
|
} else if (char === "'" || char === '"' || char === "`") {
|
|
935
925
|
inString = char;
|
|
936
926
|
} else if (char === "{") {
|
|
@@ -943,19 +933,20 @@ ${_Tokenizer.EofId}`;
|
|
|
943
933
|
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
944
934
|
return;
|
|
945
935
|
}
|
|
946
|
-
value += this.
|
|
936
|
+
value += this.code[this.i];
|
|
937
|
+
this.i++;
|
|
947
938
|
}
|
|
948
939
|
}
|
|
949
940
|
newLine() {
|
|
950
941
|
let value = "\n";
|
|
951
942
|
let nextC;
|
|
952
943
|
while (1) {
|
|
953
|
-
nextC = this.
|
|
944
|
+
nextC = this.code[this.i + 1];
|
|
954
945
|
if (nextC !== "\n") {
|
|
955
946
|
break;
|
|
956
947
|
}
|
|
957
948
|
value += nextC;
|
|
958
|
-
this.
|
|
949
|
+
this.i++;
|
|
959
950
|
}
|
|
960
951
|
if (this.isFirstToken) {
|
|
961
952
|
return;
|
|
@@ -967,7 +958,7 @@ ${_Tokenizer.EofId}`;
|
|
|
967
958
|
let nextC;
|
|
968
959
|
let isEmptyLine = false;
|
|
969
960
|
while (1) {
|
|
970
|
-
const nextChar = this.
|
|
961
|
+
const nextChar = this.code[this.i];
|
|
971
962
|
switch (nextChar) {
|
|
972
963
|
case " ":
|
|
973
964
|
nextC = this.Tab;
|
|
@@ -990,7 +981,7 @@ ${_Tokenizer.EofId}`;
|
|
|
990
981
|
break;
|
|
991
982
|
}
|
|
992
983
|
value += nextC;
|
|
993
|
-
this.
|
|
984
|
+
this.i++;
|
|
994
985
|
}
|
|
995
986
|
return {
|
|
996
987
|
value,
|
|
@@ -1013,7 +1004,7 @@ ${_Tokenizer.EofId}`;
|
|
|
1013
1004
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
1014
1005
|
if (currLen > prevLen) {
|
|
1015
1006
|
this.dentStack.push(currLen);
|
|
1016
|
-
this.setToken(TokenType.Indent,
|
|
1007
|
+
this.setToken(TokenType.Indent, currLen);
|
|
1017
1008
|
return indentHasLen;
|
|
1018
1009
|
}
|
|
1019
1010
|
if (currLen < prevLen) {
|
|
@@ -1072,12 +1063,12 @@ ${_Tokenizer.EofId}`;
|
|
|
1072
1063
|
let value = char;
|
|
1073
1064
|
let nextC;
|
|
1074
1065
|
while (1) {
|
|
1075
|
-
nextC = this.
|
|
1076
|
-
if (!
|
|
1066
|
+
nextC = this.code[this.i + 1];
|
|
1067
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart(nextC)) {
|
|
1077
1068
|
break;
|
|
1078
1069
|
}
|
|
1079
1070
|
value += nextC;
|
|
1080
|
-
this.
|
|
1071
|
+
this.i++;
|
|
1081
1072
|
}
|
|
1082
1073
|
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1083
1074
|
this.setToken(TokenType.Dedent, "");
|
|
@@ -1087,35 +1078,35 @@ ${_Tokenizer.EofId}`;
|
|
|
1087
1078
|
this.setToken(TokenType.Identifier, realValue);
|
|
1088
1079
|
}
|
|
1089
1080
|
str(char) {
|
|
1090
|
-
let value =
|
|
1081
|
+
let value = "";
|
|
1091
1082
|
let nextC;
|
|
1092
1083
|
let continuousBackslashCount = 0;
|
|
1093
1084
|
while (1) {
|
|
1094
|
-
nextC = this.
|
|
1095
|
-
value += nextC;
|
|
1085
|
+
nextC = this.code[this.i + 1];
|
|
1096
1086
|
const memoCount = continuousBackslashCount;
|
|
1097
1087
|
if (nextC === "\\") {
|
|
1098
1088
|
continuousBackslashCount++;
|
|
1099
1089
|
} else {
|
|
1100
1090
|
continuousBackslashCount = 0;
|
|
1101
1091
|
}
|
|
1102
|
-
this.
|
|
1092
|
+
this.i++;
|
|
1103
1093
|
if (nextC === char && memoCount % 2 === 0) {
|
|
1104
1094
|
break;
|
|
1105
1095
|
}
|
|
1096
|
+
value += nextC;
|
|
1106
1097
|
}
|
|
1107
|
-
this.setToken(TokenType.Identifier,
|
|
1098
|
+
this.setToken(TokenType.Identifier, value);
|
|
1108
1099
|
}
|
|
1109
1100
|
number(char) {
|
|
1110
1101
|
let value = char;
|
|
1111
1102
|
let nextC;
|
|
1112
1103
|
while (1) {
|
|
1113
|
-
nextC = this.
|
|
1104
|
+
nextC = this.code[this.i + 1];
|
|
1114
1105
|
if (!bobeShared.isNum(nextC)) {
|
|
1115
1106
|
break;
|
|
1116
1107
|
}
|
|
1117
1108
|
value += nextC;
|
|
1118
|
-
this.
|
|
1109
|
+
this.i++;
|
|
1119
1110
|
}
|
|
1120
1111
|
this.setToken(TokenType.Identifier, Number(value));
|
|
1121
1112
|
}
|
|
@@ -1135,8 +1126,6 @@ ${_Tokenizer.EofId}`;
|
|
|
1135
1126
|
}
|
|
1136
1127
|
}
|
|
1137
1128
|
};
|
|
1138
|
-
/** 匹配标识符 */
|
|
1139
|
-
_Tokenizer.IdExp = /[\d\w\/]/;
|
|
1140
1129
|
/** Eof 标识符的值 */
|
|
1141
1130
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1142
1131
|
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|