bobe 0.0.15 → 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 +335 -285
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +337 -287
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +54 -63
- package/dist/index.umd.js +335 -285
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -14,25 +14,27 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
|
14
14
|
TokenType2[TokenType2["InsertionExp"] = 128] = "InsertionExp";
|
|
15
15
|
return TokenType2;
|
|
16
16
|
})(TokenType || {});
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
var FakeType = /* @__PURE__ */ ((FakeType2) => {
|
|
18
|
+
FakeType2[FakeType2["If"] = 1] = "If";
|
|
19
|
+
FakeType2[FakeType2["Fail"] = 2] = "Fail";
|
|
20
|
+
FakeType2[FakeType2["Else"] = 4] = "Else";
|
|
21
|
+
FakeType2[FakeType2["For"] = 8] = "For";
|
|
22
|
+
FakeType2[FakeType2["Component"] = 16] = "Component";
|
|
23
|
+
FakeType2[FakeType2["Fragment"] = 32] = "Fragment";
|
|
24
|
+
FakeType2[FakeType2["ForItem"] = 64] = "ForItem";
|
|
25
|
+
return FakeType2;
|
|
26
|
+
})(FakeType || {});
|
|
27
|
+
const CondBit = 1 /* If */ | 2 /* Fail */ | 4 /* Else */;
|
|
28
|
+
const LogicalBit = 1 /* If */ | 2 /* Fail */ | 4 /* Else */ | 8 /* For */ | 64 /* ForItem */;
|
|
29
|
+
const TokenizerSwitcherBit = 16 /* Component */ | 32 /* Fragment */;
|
|
30
|
+
var NodeSort = /* @__PURE__ */ ((NodeSort2) => {
|
|
31
|
+
NodeSort2[NodeSort2["Logic"] = 1] = "Logic";
|
|
32
|
+
NodeSort2[NodeSort2["Real"] = 2] = "Real";
|
|
33
|
+
NodeSort2[NodeSort2["Component"] = 4] = "Component";
|
|
34
|
+
NodeSort2[NodeSort2["CtxProvider"] = 8] = "CtxProvider";
|
|
35
|
+
NodeSort2[NodeSort2["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
|
|
36
|
+
return NodeSort2;
|
|
37
|
+
})(NodeSort || {});
|
|
36
38
|
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
37
39
|
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
38
40
|
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
@@ -40,140 +42,123 @@ var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
|
40
42
|
})(TerpEvt || {});
|
|
41
43
|
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
42
44
|
|
|
43
|
-
class
|
|
45
|
+
class MultiTypeStack {
|
|
44
46
|
constructor() {
|
|
47
|
+
// 记录全局栈顶
|
|
45
48
|
this.top = null;
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
this.lastNodes = {};
|
|
49
|
+
// 记录每个类别的当前最新节点(各分类的“栈顶”)
|
|
50
|
+
this.typeTops = {};
|
|
49
51
|
this.length = 0;
|
|
50
52
|
}
|
|
51
53
|
/**
|
|
52
|
-
*
|
|
53
|
-
* @param
|
|
54
|
+
* 入栈操作
|
|
55
|
+
* @param value 数据
|
|
56
|
+
* @param bits 该节点所属的类别数组
|
|
54
57
|
*/
|
|
55
|
-
push(
|
|
56
|
-
var _a;
|
|
58
|
+
push(value, bits) {
|
|
57
59
|
const newNode = {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
value,
|
|
61
|
+
types: bits,
|
|
62
|
+
prevGlobal: this.top,
|
|
63
|
+
prevByType: {}
|
|
62
64
|
};
|
|
65
|
+
let bit;
|
|
66
|
+
while (1) {
|
|
67
|
+
bit = bits & ~bits + 1;
|
|
68
|
+
if (!bit) break;
|
|
69
|
+
bits &= ~bit;
|
|
70
|
+
newNode.prevByType[bit] = this.typeTops[bit] || void 0;
|
|
71
|
+
this.typeTops[bit] = newNode;
|
|
72
|
+
}
|
|
63
73
|
this.top = newNode;
|
|
64
74
|
this.length++;
|
|
65
|
-
this.lastNodes[type] = newNode;
|
|
66
75
|
}
|
|
67
76
|
/**
|
|
68
77
|
* 出栈操作
|
|
69
|
-
* @returns 原始节点数据或 null
|
|
70
78
|
*/
|
|
71
79
|
pop() {
|
|
72
|
-
if (!this.top) return
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
if (!this.top) return void 0;
|
|
81
|
+
const poppedNode = this.top;
|
|
82
|
+
let { types: bits } = poppedNode;
|
|
83
|
+
let bit;
|
|
84
|
+
while (1) {
|
|
85
|
+
bit = bits & ~bits + 1;
|
|
86
|
+
if (!bit) break;
|
|
87
|
+
bits &= ~bit;
|
|
88
|
+
this.typeTops[bit] = poppedNode.prevByType[bit];
|
|
89
|
+
}
|
|
90
|
+
this.top = poppedNode.prevGlobal;
|
|
76
91
|
this.length--;
|
|
77
|
-
return
|
|
92
|
+
return [poppedNode.value, poppedNode.types];
|
|
78
93
|
}
|
|
79
94
|
/**
|
|
80
|
-
*
|
|
95
|
+
* 获取某个类别的当前“顶部”元素
|
|
81
96
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
return this.top.prevSameType.data;
|
|
87
|
-
}
|
|
88
|
-
findPrevSameType(cb) {
|
|
89
|
-
if (!this.top) {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
let point = this.top.prevSameType;
|
|
93
|
-
while (point) {
|
|
94
|
-
if (cb(point.data)) {
|
|
95
|
-
return point.data;
|
|
96
|
-
}
|
|
97
|
-
point = point.prevSameType;
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
97
|
+
peekByType(cat) {
|
|
98
|
+
var _a;
|
|
99
|
+
return (_a = this.typeTops[cat]) == null ? void 0 : _a.value;
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
get peekType() {
|
|
105
|
-
return this.top ? this.top.type : null;
|
|
101
|
+
peekType() {
|
|
102
|
+
var _a;
|
|
103
|
+
return (_a = this.top) == null ? void 0 : _a.types;
|
|
106
104
|
}
|
|
107
105
|
/**
|
|
108
|
-
*
|
|
106
|
+
* 获取全局栈顶
|
|
109
107
|
*/
|
|
110
108
|
peek() {
|
|
111
|
-
|
|
109
|
+
var _a;
|
|
110
|
+
return (_a = this.top) == null ? void 0 : _a.value;
|
|
112
111
|
}
|
|
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
|
+
// }
|
|
113
140
|
}
|
|
114
141
|
|
|
115
|
-
var __defProp$1 = Object.defineProperty;
|
|
116
|
-
var __defProps$1 = Object.defineProperties;
|
|
117
|
-
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
118
|
-
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
119
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
120
|
-
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
121
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
122
|
-
var __spreadValues$1 = (a, b) => {
|
|
123
|
-
for (var prop in b || (b = {}))
|
|
124
|
-
if (__hasOwnProp$1.call(b, prop))
|
|
125
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
126
|
-
if (__getOwnPropSymbols$1)
|
|
127
|
-
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
128
|
-
if (__propIsEnum$1.call(b, prop))
|
|
129
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
130
|
-
}
|
|
131
|
-
return a;
|
|
132
|
-
};
|
|
133
|
-
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
134
142
|
const tap = new bobeShared.BaseEvent();
|
|
135
143
|
class Interpreter {
|
|
136
144
|
constructor(tokenizer) {
|
|
137
145
|
this.tokenizer = tokenizer;
|
|
138
|
-
|
|
139
|
-
this.HookId = "_h_o_o_k_";
|
|
140
|
-
/** 用于渲染的数据 */
|
|
141
|
-
this.data = {};
|
|
142
|
-
/** 模板字符串动态节点索引 */
|
|
143
|
-
this.hookI = 0;
|
|
144
|
-
this._hook = (props) => {
|
|
145
|
-
const value = this.tokenizer.token.value;
|
|
146
|
-
const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
|
|
147
|
-
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
148
|
-
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
149
|
-
if (this.hook && isStaticHook) {
|
|
150
|
-
const hookI = Number(value.slice(this.HookId.length));
|
|
151
|
-
const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
|
|
152
|
-
HookId: this.HookId,
|
|
153
|
-
i: hookI
|
|
154
|
-
}));
|
|
155
|
-
this.hookI++;
|
|
156
|
-
return [hookType, res];
|
|
157
|
-
} else if (isDynamicHook) {
|
|
158
|
-
return [hookType, value];
|
|
159
|
-
}
|
|
160
|
-
return [hookType, value];
|
|
161
|
-
};
|
|
146
|
+
this.rootComponent = null;
|
|
162
147
|
}
|
|
163
148
|
isLogicNode(node) {
|
|
164
|
-
return node && node.__logicType &
|
|
149
|
+
return node && node.__logicType & LogicalBit;
|
|
165
150
|
}
|
|
166
|
-
program(root, before) {
|
|
167
|
-
var _a;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const ctx = {
|
|
151
|
+
program(root, componentNode, before) {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
this.rootComponent = componentNode;
|
|
154
|
+
this.tokenizer.nextToken();
|
|
155
|
+
const stack = new MultiTypeStack();
|
|
156
|
+
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
157
|
+
stack.push(
|
|
158
|
+
{ node: componentNode, prev: null },
|
|
159
|
+
NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher
|
|
160
|
+
);
|
|
161
|
+
const ctx = this.ctx = {
|
|
177
162
|
realParent: root,
|
|
178
163
|
prevSibling: before,
|
|
179
164
|
current: null,
|
|
@@ -189,14 +174,14 @@ class Interpreter {
|
|
|
189
174
|
}
|
|
190
175
|
const token = this.tokenizer.token;
|
|
191
176
|
if (token.type & TokenType.Indent) {
|
|
192
|
-
this.tokenizer.
|
|
177
|
+
this.tokenizer.nextToken();
|
|
193
178
|
const isLogicNode = this.isLogicNode(ctx.current);
|
|
194
179
|
stack.push(
|
|
195
180
|
{
|
|
196
181
|
node: ctx.current,
|
|
197
182
|
prev: ctx.prevSibling
|
|
198
183
|
},
|
|
199
|
-
ctx.current.__logicType ?
|
|
184
|
+
!ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider
|
|
200
185
|
);
|
|
201
186
|
if (ctx.current.__logicType) {
|
|
202
187
|
if (isLogicNode) {
|
|
@@ -212,28 +197,31 @@ class Interpreter {
|
|
|
212
197
|
continue;
|
|
213
198
|
}
|
|
214
199
|
if (ctx.current) {
|
|
215
|
-
if (stack.length ===
|
|
200
|
+
if (stack.length === 2 && !ctx.prevSibling) {
|
|
216
201
|
ctx.prevSibling = before;
|
|
217
202
|
}
|
|
218
203
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
219
204
|
}
|
|
220
205
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
221
|
-
this.tokenizer.
|
|
222
|
-
const { node: parent, prev } = stack.
|
|
206
|
+
this.tokenizer.nextToken();
|
|
207
|
+
const [{ node: parent, prev }, sort] = stack.pop();
|
|
223
208
|
if (!parent.__logicType) {
|
|
224
|
-
const prevSameType = stack.
|
|
209
|
+
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
225
210
|
ctx.realParent = (prevSameType == null ? void 0 : prevSameType.node) || root;
|
|
226
211
|
} else {
|
|
227
|
-
if (
|
|
228
|
-
const parentLogic = (_a = stack.
|
|
212
|
+
if (sort & NodeSort.Logic) {
|
|
213
|
+
const parentLogic = (_a = stack.peekByType(NodeSort.Logic)) == null ? void 0 : _a.node;
|
|
229
214
|
if (parentLogic) {
|
|
230
215
|
aoye.setPulling(parentLogic.effect.ins);
|
|
231
216
|
} else {
|
|
232
217
|
aoye.setPulling(rootPulling);
|
|
233
218
|
}
|
|
234
219
|
}
|
|
220
|
+
if (sort & NodeSort.TokenizerSwitcher) {
|
|
221
|
+
const switcher = (_b = stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _b.node;
|
|
222
|
+
this.tokenizer = switcher.tokenizer;
|
|
223
|
+
}
|
|
235
224
|
}
|
|
236
|
-
stack.pop();
|
|
237
225
|
ctx.prevSibling = prev;
|
|
238
226
|
ctx.current = parent;
|
|
239
227
|
} else {
|
|
@@ -243,10 +231,15 @@ class Interpreter {
|
|
|
243
231
|
}
|
|
244
232
|
return componentNode;
|
|
245
233
|
}
|
|
234
|
+
switcherIsRootComponent() {
|
|
235
|
+
var _a;
|
|
236
|
+
const currentSwitcher = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
237
|
+
return currentSwitcher === this.rootComponent;
|
|
238
|
+
}
|
|
246
239
|
insertAfterAnchor(ctx) {
|
|
247
240
|
const { realParent, prevSibling, stack, before } = ctx;
|
|
248
241
|
const afterAnchor = this.createAnchor();
|
|
249
|
-
ctx.prevSibling = stack.length ===
|
|
242
|
+
ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
250
243
|
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
251
244
|
return afterAnchor;
|
|
252
245
|
}
|
|
@@ -293,7 +286,7 @@ class Interpreter {
|
|
|
293
286
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
294
287
|
* */
|
|
295
288
|
declaration(ctx) {
|
|
296
|
-
const [hookType, value] = this._hook({});
|
|
289
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
297
290
|
let _node;
|
|
298
291
|
if (value === "if" || value === "else" || value === "fail") {
|
|
299
292
|
return this.condDeclaration(ctx);
|
|
@@ -302,34 +295,42 @@ class Interpreter {
|
|
|
302
295
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
303
296
|
_node = this.componentDeclaration(value, ctx);
|
|
304
297
|
} else if (typeof value === "function") {
|
|
305
|
-
_node = this.fragmentDeclaration(value);
|
|
298
|
+
_node = this.fragmentDeclaration(value, ctx);
|
|
306
299
|
} else {
|
|
307
300
|
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
308
301
|
}
|
|
309
302
|
} else {
|
|
310
|
-
|
|
303
|
+
const data = this.getData();
|
|
304
|
+
Boolean(data[aoye.Keys.Raw][value]);
|
|
311
305
|
new Function("data", `let v;with(data){v=(${value})};return v`);
|
|
312
306
|
_node = this.createNode(value);
|
|
313
307
|
}
|
|
314
308
|
} else {
|
|
315
309
|
_node = this.createNode(value);
|
|
316
310
|
}
|
|
317
|
-
this.tokenizer.
|
|
311
|
+
this.tokenizer.nextToken();
|
|
318
312
|
this.headerLine(_node);
|
|
319
313
|
this.extensionLines(_node);
|
|
320
|
-
if (_node.__logicType ===
|
|
314
|
+
if (_node.__logicType === FakeType.Component) {
|
|
321
315
|
tap.once(TerpEvt.HandledComponentNode, (node) => _node = node);
|
|
322
316
|
tap.emit(TerpEvt.AllAttrGot);
|
|
323
317
|
}
|
|
324
318
|
return _node;
|
|
325
319
|
}
|
|
320
|
+
getData() {
|
|
321
|
+
const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
|
|
322
|
+
return node.data || node.owner.data;
|
|
323
|
+
}
|
|
326
324
|
// TODO: 指定挂载位置
|
|
327
|
-
fragmentDeclaration(renderFragment) {
|
|
325
|
+
fragmentDeclaration(renderFragment, ctx) {
|
|
326
|
+
const data = this.getData();
|
|
327
|
+
const tokenizer = renderFragment.call(data, this.opt, { data, root: "", anchor: "" });
|
|
328
328
|
const fragmentNode = {
|
|
329
|
-
__logicType:
|
|
330
|
-
realParent: null
|
|
329
|
+
__logicType: FakeType.Fragment,
|
|
330
|
+
realParent: null,
|
|
331
|
+
tokenizer,
|
|
332
|
+
data: null
|
|
331
333
|
};
|
|
332
|
-
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
333
334
|
return fragmentNode;
|
|
334
335
|
}
|
|
335
336
|
/**
|
|
@@ -340,15 +341,17 @@ class Interpreter {
|
|
|
340
341
|
*
|
|
341
342
|
* mapKey 映射, 对应子组件的属性
|
|
342
343
|
* */
|
|
343
|
-
onePropParsed(node, key, value, valueIsMapKey, hookI) {
|
|
344
|
-
if (
|
|
344
|
+
onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
|
|
345
|
+
if (isFn) {
|
|
346
|
+
this.setProp(node, key, value, hookI);
|
|
347
|
+
} else if (typeof value === "function") {
|
|
345
348
|
aoye.effect(() => {
|
|
346
349
|
const res = value();
|
|
347
350
|
this.setProp(node, key, res, hookI);
|
|
348
351
|
});
|
|
349
352
|
} else if (valueIsMapKey) {
|
|
350
353
|
aoye.effect(() => {
|
|
351
|
-
const res =
|
|
354
|
+
const res = data[value];
|
|
352
355
|
this.setProp(node, key, res, hookI);
|
|
353
356
|
});
|
|
354
357
|
} else {
|
|
@@ -357,10 +360,18 @@ class Interpreter {
|
|
|
357
360
|
}
|
|
358
361
|
componentDeclaration(Component, ctx) {
|
|
359
362
|
const child = Component.new();
|
|
363
|
+
const componentNode = {
|
|
364
|
+
__logicType: FakeType.Component,
|
|
365
|
+
realParent: ctx.realParent,
|
|
366
|
+
data: child,
|
|
367
|
+
tokenizer: null
|
|
368
|
+
};
|
|
360
369
|
const prevOnePropParsed = this.onePropParsed;
|
|
361
|
-
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
362
|
-
if (
|
|
363
|
-
aoye.
|
|
370
|
+
this.onePropParsed = (data, node, key, value, valueIsMapKey, isFn, hookI) => {
|
|
371
|
+
if (isFn) {
|
|
372
|
+
child[aoye.Keys.Raw][key] = value;
|
|
373
|
+
} else if (valueIsMapKey) {
|
|
374
|
+
aoye.shareSignal(data, value, child, key);
|
|
364
375
|
} else if (typeof value === "function") {
|
|
365
376
|
const meta = child[aoye.Keys.Meta];
|
|
366
377
|
const cells = meta.cells;
|
|
@@ -370,37 +381,41 @@ class Interpreter {
|
|
|
370
381
|
child[aoye.Keys.Raw][key] = value;
|
|
371
382
|
}
|
|
372
383
|
};
|
|
373
|
-
|
|
384
|
+
componentNode.realAfter = this.insertAfterAnchor(ctx);
|
|
374
385
|
const { realParent, prevSibling } = ctx;
|
|
375
386
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
376
|
-
const parent = realParent;
|
|
377
|
-
const prev = prevSibling;
|
|
378
387
|
this.onePropParsed = prevOnePropParsed;
|
|
379
|
-
const
|
|
380
|
-
componentNode.
|
|
388
|
+
const subTkr = child["ui"](true);
|
|
389
|
+
componentNode.tokenizer = subTkr;
|
|
390
|
+
this.tokenizer = subTkr;
|
|
381
391
|
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
382
392
|
});
|
|
383
|
-
return
|
|
393
|
+
return componentNode;
|
|
384
394
|
}
|
|
385
395
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
386
396
|
condDeclaration(ctx) {
|
|
397
|
+
var _a;
|
|
387
398
|
const { prevSibling } = ctx;
|
|
388
399
|
const snapbackUp = this.tokenizer.snapshot();
|
|
389
|
-
const keyWord = this.tokenizer.
|
|
400
|
+
const keyWord = this.tokenizer.token;
|
|
401
|
+
this.tokenizer.nextToken();
|
|
390
402
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
391
|
-
const [hookType, value] = this._hook({});
|
|
403
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
392
404
|
const isElse = keyWord.value === "else";
|
|
393
405
|
const isIf = keyWord.value === "if";
|
|
394
|
-
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) &
|
|
406
|
+
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
|
|
395
407
|
const needCalcWithPrevIf = isElse && preIsCond;
|
|
408
|
+
const data = this.getData();
|
|
409
|
+
const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
396
410
|
const ifNode = {
|
|
397
|
-
__logicType: isElse ?
|
|
411
|
+
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
398
412
|
snapshot: noSelfCond ? snapbackUp : this.tokenizer.snapshot(),
|
|
399
413
|
condition: null,
|
|
400
414
|
realParent: null,
|
|
401
415
|
preCond: preIsCond ? prevSibling : null,
|
|
402
416
|
isFirstRender: true,
|
|
403
|
-
effect: null
|
|
417
|
+
effect: null,
|
|
418
|
+
owner
|
|
404
419
|
};
|
|
405
420
|
let signal;
|
|
406
421
|
if (noSelfCond) {
|
|
@@ -411,7 +426,7 @@ class Interpreter {
|
|
|
411
426
|
if (point.condition.v) {
|
|
412
427
|
return false;
|
|
413
428
|
}
|
|
414
|
-
if (point.__logicType ===
|
|
429
|
+
if (point.__logicType === FakeType.If) {
|
|
415
430
|
break;
|
|
416
431
|
}
|
|
417
432
|
point = point.preCond;
|
|
@@ -431,13 +446,13 @@ class Interpreter {
|
|
|
431
446
|
});
|
|
432
447
|
}
|
|
433
448
|
} else {
|
|
434
|
-
const valueIsMapKey = Reflect.has(
|
|
449
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
435
450
|
if (valueIsMapKey && !needCalcWithPrevIf) {
|
|
436
|
-
aoye.runWithPulling(() =>
|
|
437
|
-
const { cells } =
|
|
451
|
+
aoye.runWithPulling(() => data[value], null);
|
|
452
|
+
const { cells } = data[aoye.Keys.Meta];
|
|
438
453
|
signal = cells.get(value);
|
|
439
454
|
} else {
|
|
440
|
-
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0,
|
|
455
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
441
456
|
if (needCalcWithPrevIf) {
|
|
442
457
|
signal = aoye.$(() => {
|
|
443
458
|
let point = ifNode.preCond;
|
|
@@ -445,7 +460,7 @@ class Interpreter {
|
|
|
445
460
|
if (point.condition.v) {
|
|
446
461
|
return false;
|
|
447
462
|
}
|
|
448
|
-
if (point.__logicType ===
|
|
463
|
+
if (point.__logicType === FakeType.If) {
|
|
449
464
|
break;
|
|
450
465
|
}
|
|
451
466
|
point = point.preCond;
|
|
@@ -464,12 +479,13 @@ class Interpreter {
|
|
|
464
479
|
if (val) {
|
|
465
480
|
if (ifNode.isFirstRender) {
|
|
466
481
|
if (!noSelfCond) {
|
|
467
|
-
this.tokenizer.
|
|
482
|
+
this.tokenizer.nextToken();
|
|
468
483
|
}
|
|
469
|
-
this.tokenizer.
|
|
484
|
+
this.tokenizer.nextToken();
|
|
470
485
|
} else {
|
|
486
|
+
this.tokenizer = ifNode.owner.tokenizer;
|
|
471
487
|
this.tokenizer.resume(ifNode.snapshot);
|
|
472
|
-
this.program(ifNode.realParent, ifNode.realBefore);
|
|
488
|
+
this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore);
|
|
473
489
|
}
|
|
474
490
|
} else {
|
|
475
491
|
if (ifNode.isFirstRender) {
|
|
@@ -480,7 +496,7 @@ class Interpreter {
|
|
|
480
496
|
this.tokenizer.skip();
|
|
481
497
|
} else {
|
|
482
498
|
const { realBefore, realAfter, realParent } = ifNode;
|
|
483
|
-
let point = realBefore ? this.nextSib(realBefore) : this.
|
|
499
|
+
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
484
500
|
while (point !== realAfter) {
|
|
485
501
|
const next = this.nextSib(point);
|
|
486
502
|
this.remove(point, realParent, realBefore);
|
|
@@ -500,15 +516,15 @@ class Interpreter {
|
|
|
500
516
|
*/
|
|
501
517
|
extensionLines(_node) {
|
|
502
518
|
while (1) {
|
|
503
|
-
if (
|
|
519
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
504
520
|
return;
|
|
505
521
|
}
|
|
506
|
-
this.tokenizer.
|
|
522
|
+
this.tokenizer.nextToken();
|
|
507
523
|
this.attributeList(_node);
|
|
508
|
-
if (
|
|
524
|
+
if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
509
525
|
return;
|
|
510
526
|
}
|
|
511
|
-
this.tokenizer.
|
|
527
|
+
this.tokenizer.nextToken();
|
|
512
528
|
}
|
|
513
529
|
}
|
|
514
530
|
/**
|
|
@@ -518,7 +534,7 @@ class Interpreter {
|
|
|
518
534
|
*/
|
|
519
535
|
headerLine(_node) {
|
|
520
536
|
this.attributeList(_node);
|
|
521
|
-
this.tokenizer.
|
|
537
|
+
this.tokenizer.nextToken();
|
|
522
538
|
}
|
|
523
539
|
/**
|
|
524
540
|
* 属性列表:
|
|
@@ -528,30 +544,33 @@ class Interpreter {
|
|
|
528
544
|
*
|
|
529
545
|
* <attribute> ::= <key> = <value>
|
|
530
546
|
* 1. 普通节点 执行 setProps 🪝
|
|
531
|
-
* 2. 组件节点
|
|
547
|
+
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
532
548
|
*/
|
|
533
549
|
attributeList(_node) {
|
|
534
550
|
let key, eq;
|
|
535
|
-
|
|
551
|
+
const data = this.getData();
|
|
552
|
+
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
536
553
|
if (key == null) {
|
|
537
554
|
key = this.tokenizer.token.value;
|
|
538
555
|
} else if (eq == null) {
|
|
539
556
|
eq = "=";
|
|
540
557
|
} else {
|
|
541
|
-
const [hookType, value] = this._hook({});
|
|
558
|
+
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
559
|
+
const rawVal = data[aoye.Keys.Raw][value];
|
|
560
|
+
const isFn = typeof rawVal === "function";
|
|
542
561
|
if (hookType === "dynamic") {
|
|
543
|
-
const valueIsMapKey = Reflect.has(
|
|
544
|
-
const fn = valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0,
|
|
545
|
-
this.onePropParsed(_node, key, fn, valueIsMapKey,
|
|
562
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
563
|
+
const fn = isFn ? rawVal : valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
564
|
+
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
546
565
|
} else if (hookType === "static") {
|
|
547
|
-
this.onePropParsed(_node, key, value, false,
|
|
566
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
548
567
|
} else {
|
|
549
|
-
this.onePropParsed(_node, key, value, false,
|
|
568
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
550
569
|
}
|
|
551
570
|
key = null;
|
|
552
571
|
eq = null;
|
|
553
572
|
}
|
|
554
|
-
this.tokenizer.
|
|
573
|
+
this.tokenizer.nextToken();
|
|
555
574
|
}
|
|
556
575
|
}
|
|
557
576
|
config(opt) {
|
|
@@ -568,7 +587,7 @@ class Interpreter {
|
|
|
568
587
|
nextSib(node) {
|
|
569
588
|
return node.nextSibling;
|
|
570
589
|
}
|
|
571
|
-
|
|
590
|
+
firstChild(node) {
|
|
572
591
|
return node.firstChild;
|
|
573
592
|
}
|
|
574
593
|
_createAnchor() {
|
|
@@ -612,28 +631,35 @@ class Interpreter {
|
|
|
612
631
|
setProp(node, key, value, hookI) {
|
|
613
632
|
node.props[key] = value;
|
|
614
633
|
}
|
|
615
|
-
init(fragments) {
|
|
616
|
-
if (typeof fragments === "string") {
|
|
617
|
-
this.tokenizer.setCode(fragments);
|
|
618
|
-
} else {
|
|
619
|
-
let code = "";
|
|
620
|
-
for (let i = 0; i < fragments.length - 1; i++) {
|
|
621
|
-
const fragment = fragments[i];
|
|
622
|
-
code += fragment + `${this.HookId}${i}`;
|
|
623
|
-
}
|
|
624
|
-
this.tokenizer.setCode(code + fragments[fragments.length - 1]);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
634
|
}
|
|
628
635
|
|
|
636
|
+
var __defProp = Object.defineProperty;
|
|
637
|
+
var __defProps = Object.defineProperties;
|
|
638
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
639
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
640
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
641
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
642
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
643
|
+
var __spreadValues = (a, b) => {
|
|
644
|
+
for (var prop in b || (b = {}))
|
|
645
|
+
if (__hasOwnProp.call(b, prop))
|
|
646
|
+
__defNormalProp(a, prop, b[prop]);
|
|
647
|
+
if (__getOwnPropSymbols)
|
|
648
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
649
|
+
if (__propIsEnum.call(b, prop))
|
|
650
|
+
__defNormalProp(a, prop, b[prop]);
|
|
651
|
+
}
|
|
652
|
+
return a;
|
|
653
|
+
};
|
|
654
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
629
655
|
const _Tokenizer = class _Tokenizer {
|
|
630
|
-
constructor() {
|
|
656
|
+
constructor(hook, isSubToken) {
|
|
657
|
+
this.hook = hook;
|
|
658
|
+
this.isSubToken = isSubToken;
|
|
631
659
|
/** 缩进大小 默认 2 */
|
|
632
660
|
this.TabSize = 2;
|
|
633
661
|
/** 缩进字符 */
|
|
634
662
|
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
635
|
-
/** 匹配标识符 */
|
|
636
|
-
this.IdExp = /[\d\w\/]/;
|
|
637
663
|
/** 回车后需要判断缩进 */
|
|
638
664
|
this.needIndent = false;
|
|
639
665
|
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
@@ -642,6 +668,7 @@ const _Tokenizer = class _Tokenizer {
|
|
|
642
668
|
this.dentStack = [0];
|
|
643
669
|
/** 当前字符 index */
|
|
644
670
|
this.i = 0;
|
|
671
|
+
// TODO: 生产环境不需要这个,导致不必要的内存占用
|
|
645
672
|
this.handledTokens = [];
|
|
646
673
|
/**
|
|
647
674
|
* 有些标识符能产生多个 token
|
|
@@ -652,6 +679,31 @@ const _Tokenizer = class _Tokenizer {
|
|
|
652
679
|
* parent2 <- 产生两个 dedent
|
|
653
680
|
*/
|
|
654
681
|
this.waitingTokens = new bobeShared.Queue();
|
|
682
|
+
/** 模板字符串动态节点的占位符 */
|
|
683
|
+
this.HookId = "_h_o_o_k_";
|
|
684
|
+
/** 模板字符串动态节点索引 */
|
|
685
|
+
this.hookI = 0;
|
|
686
|
+
this._hook = (props) => {
|
|
687
|
+
const value = this.token.value;
|
|
688
|
+
const isDynamicHook = this.token.type & TokenType.InsertionExp;
|
|
689
|
+
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
690
|
+
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
691
|
+
if (this.hook && isStaticHook) {
|
|
692
|
+
const hookI = Number(value.slice(this.HookId.length));
|
|
693
|
+
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
694
|
+
HookId: this.HookId,
|
|
695
|
+
i: hookI
|
|
696
|
+
}));
|
|
697
|
+
return [hookType, res, hookI];
|
|
698
|
+
} else if (isDynamicHook) {
|
|
699
|
+
return [hookType, value];
|
|
700
|
+
}
|
|
701
|
+
return [hookType, value];
|
|
702
|
+
};
|
|
703
|
+
if (isSubToken) {
|
|
704
|
+
this.setToken(TokenType.Indent, "");
|
|
705
|
+
this.isFirstToken = true;
|
|
706
|
+
}
|
|
655
707
|
}
|
|
656
708
|
consume() {
|
|
657
709
|
const token = this.token;
|
|
@@ -678,16 +730,16 @@ const _Tokenizer = class _Tokenizer {
|
|
|
678
730
|
let skipFragment = ``;
|
|
679
731
|
this.token = void 0;
|
|
680
732
|
while (1) {
|
|
681
|
-
const char = this.
|
|
733
|
+
const char = this.code[this.i];
|
|
682
734
|
if (char === "\n") {
|
|
683
735
|
needIndent = true;
|
|
684
736
|
skipFragment += char;
|
|
685
|
-
this.
|
|
737
|
+
this.i++;
|
|
686
738
|
continue;
|
|
687
739
|
}
|
|
688
740
|
if (!needIndent) {
|
|
689
741
|
skipFragment += char;
|
|
690
|
-
this.
|
|
742
|
+
this.i++;
|
|
691
743
|
continue;
|
|
692
744
|
}
|
|
693
745
|
needIndent = false;
|
|
@@ -740,21 +792,6 @@ ${_Tokenizer.EofId}`;
|
|
|
740
792
|
if (!this.token) return false;
|
|
741
793
|
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
742
794
|
}
|
|
743
|
-
get char() {
|
|
744
|
-
return this.code[this.i];
|
|
745
|
-
}
|
|
746
|
-
get prev() {
|
|
747
|
-
return this.code[this.i - 1];
|
|
748
|
-
}
|
|
749
|
-
get after() {
|
|
750
|
-
return this.code[this.i + 1];
|
|
751
|
-
}
|
|
752
|
-
next() {
|
|
753
|
-
const prev = this.code[this.i];
|
|
754
|
-
this.i++;
|
|
755
|
-
const curr = this.code[this.i];
|
|
756
|
-
return [prev, curr];
|
|
757
|
-
}
|
|
758
795
|
setToken(type, value) {
|
|
759
796
|
this.token = {
|
|
760
797
|
type,
|
|
@@ -763,10 +800,6 @@ ${_Tokenizer.EofId}`;
|
|
|
763
800
|
};
|
|
764
801
|
this.isFirstToken = false;
|
|
765
802
|
}
|
|
766
|
-
testId(value) {
|
|
767
|
-
if (typeof value !== "string") return false;
|
|
768
|
-
return this.IdExp.test(value);
|
|
769
|
-
}
|
|
770
803
|
nextToken() {
|
|
771
804
|
try {
|
|
772
805
|
if (this.isEof()) {
|
|
@@ -782,7 +815,7 @@ ${_Tokenizer.EofId}`;
|
|
|
782
815
|
if (this.needIndent) {
|
|
783
816
|
this.dent();
|
|
784
817
|
} else {
|
|
785
|
-
|
|
818
|
+
const char = this.code[this.i];
|
|
786
819
|
switch (char) {
|
|
787
820
|
case " ":
|
|
788
821
|
case " ":
|
|
@@ -813,12 +846,12 @@ ${_Tokenizer.EofId}`;
|
|
|
813
846
|
this.number(char);
|
|
814
847
|
break;
|
|
815
848
|
}
|
|
816
|
-
if (
|
|
849
|
+
if (typeof char === "string" && bobeShared.matchIdStart(char)) {
|
|
817
850
|
this.identifier(char);
|
|
818
851
|
}
|
|
819
852
|
break;
|
|
820
853
|
}
|
|
821
|
-
this.
|
|
854
|
+
this.i++;
|
|
822
855
|
}
|
|
823
856
|
if (this.token) {
|
|
824
857
|
break;
|
|
@@ -827,6 +860,7 @@ ${_Tokenizer.EofId}`;
|
|
|
827
860
|
return this.token;
|
|
828
861
|
} catch (error) {
|
|
829
862
|
console.error(error);
|
|
863
|
+
return this.token;
|
|
830
864
|
} finally {
|
|
831
865
|
this.handledTokens.push(this.token);
|
|
832
866
|
}
|
|
@@ -838,17 +872,17 @@ ${_Tokenizer.EofId}`;
|
|
|
838
872
|
this.setToken(TokenType.Pipe, "|");
|
|
839
873
|
}
|
|
840
874
|
dynamic(char) {
|
|
841
|
-
let nextC = this.
|
|
875
|
+
let nextC = this.code[this.i + 1];
|
|
842
876
|
if (nextC !== "{") {
|
|
843
877
|
return false;
|
|
844
878
|
}
|
|
845
|
-
this.
|
|
879
|
+
this.i++;
|
|
846
880
|
let value = "${";
|
|
847
881
|
let innerBrace = 0;
|
|
848
882
|
while (1) {
|
|
849
|
-
nextC = this.
|
|
883
|
+
nextC = this.code[this.i + 1];
|
|
850
884
|
value += nextC;
|
|
851
|
-
this.
|
|
885
|
+
this.i++;
|
|
852
886
|
if (nextC === "{") {
|
|
853
887
|
innerBrace++;
|
|
854
888
|
}
|
|
@@ -865,13 +899,14 @@ ${_Tokenizer.EofId}`;
|
|
|
865
899
|
brace() {
|
|
866
900
|
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
867
901
|
while (1) {
|
|
868
|
-
const char = this.
|
|
869
|
-
const nextChar = this.
|
|
902
|
+
const char = this.code[this.i];
|
|
903
|
+
const nextChar = this.code[this.i + 1];
|
|
870
904
|
if (inComment === "single" && char === "\n") {
|
|
871
905
|
inComment = null;
|
|
872
906
|
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
873
907
|
inComment = null;
|
|
874
|
-
value += this.
|
|
908
|
+
value += this.code[this.i];
|
|
909
|
+
this.i++;
|
|
875
910
|
} else if (inString) {
|
|
876
911
|
if (char === inString && backslashCount % 2 === 0) {
|
|
877
912
|
inString = null;
|
|
@@ -880,10 +915,12 @@ ${_Tokenizer.EofId}`;
|
|
|
880
915
|
} else {
|
|
881
916
|
if (char === "/" && nextChar === "/") {
|
|
882
917
|
inComment = "single";
|
|
883
|
-
value += this.
|
|
918
|
+
value += this.code[this.i];
|
|
919
|
+
this.i++;
|
|
884
920
|
} else if (char === "/" && nextChar === "*") {
|
|
885
921
|
inComment = "multi";
|
|
886
|
-
value += this.
|
|
922
|
+
value += this.code[this.i];
|
|
923
|
+
this.i++;
|
|
887
924
|
} else if (char === "'" || char === '"' || char === "`") {
|
|
888
925
|
inString = char;
|
|
889
926
|
} else if (char === "{") {
|
|
@@ -896,19 +933,20 @@ ${_Tokenizer.EofId}`;
|
|
|
896
933
|
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
897
934
|
return;
|
|
898
935
|
}
|
|
899
|
-
value += this.
|
|
936
|
+
value += this.code[this.i];
|
|
937
|
+
this.i++;
|
|
900
938
|
}
|
|
901
939
|
}
|
|
902
940
|
newLine() {
|
|
903
941
|
let value = "\n";
|
|
904
942
|
let nextC;
|
|
905
943
|
while (1) {
|
|
906
|
-
nextC = this.
|
|
944
|
+
nextC = this.code[this.i + 1];
|
|
907
945
|
if (nextC !== "\n") {
|
|
908
946
|
break;
|
|
909
947
|
}
|
|
910
948
|
value += nextC;
|
|
911
|
-
this.
|
|
949
|
+
this.i++;
|
|
912
950
|
}
|
|
913
951
|
if (this.isFirstToken) {
|
|
914
952
|
return;
|
|
@@ -920,7 +958,7 @@ ${_Tokenizer.EofId}`;
|
|
|
920
958
|
let nextC;
|
|
921
959
|
let isEmptyLine = false;
|
|
922
960
|
while (1) {
|
|
923
|
-
const nextChar = this.
|
|
961
|
+
const nextChar = this.code[this.i];
|
|
924
962
|
switch (nextChar) {
|
|
925
963
|
case " ":
|
|
926
964
|
nextC = this.Tab;
|
|
@@ -943,7 +981,7 @@ ${_Tokenizer.EofId}`;
|
|
|
943
981
|
break;
|
|
944
982
|
}
|
|
945
983
|
value += nextC;
|
|
946
|
-
this.
|
|
984
|
+
this.i++;
|
|
947
985
|
}
|
|
948
986
|
return {
|
|
949
987
|
value,
|
|
@@ -966,7 +1004,7 @@ ${_Tokenizer.EofId}`;
|
|
|
966
1004
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
967
1005
|
if (currLen > prevLen) {
|
|
968
1006
|
this.dentStack.push(currLen);
|
|
969
|
-
this.setToken(TokenType.Indent,
|
|
1007
|
+
this.setToken(TokenType.Indent, currLen);
|
|
970
1008
|
return indentHasLen;
|
|
971
1009
|
}
|
|
972
1010
|
if (currLen < prevLen) {
|
|
@@ -998,13 +1036,25 @@ ${_Tokenizer.EofId}`;
|
|
|
998
1036
|
const yes = this.dentStack.length === 1;
|
|
999
1037
|
if (yes) {
|
|
1000
1038
|
if (!this.token) {
|
|
1001
|
-
this.
|
|
1039
|
+
if (this.isSubToken) {
|
|
1040
|
+
this.setToken(TokenType.Dedent, "");
|
|
1041
|
+
} else {
|
|
1042
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
1043
|
+
}
|
|
1002
1044
|
} else {
|
|
1003
|
-
this.
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1045
|
+
if (this.isSubToken) {
|
|
1046
|
+
this.waitingTokens.push({
|
|
1047
|
+
type: TokenType.Dedent,
|
|
1048
|
+
typeName: TokenType[TokenType.Dedent],
|
|
1049
|
+
value: ""
|
|
1050
|
+
});
|
|
1051
|
+
} else {
|
|
1052
|
+
this.waitingTokens.push({
|
|
1053
|
+
type: TokenType.Identifier,
|
|
1054
|
+
typeName: TokenType[TokenType.Identifier],
|
|
1055
|
+
value: _Tokenizer.EofId
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1008
1058
|
}
|
|
1009
1059
|
}
|
|
1010
1060
|
return yes;
|
|
@@ -1013,98 +1063,98 @@ ${_Tokenizer.EofId}`;
|
|
|
1013
1063
|
let value = char;
|
|
1014
1064
|
let nextC;
|
|
1015
1065
|
while (1) {
|
|
1016
|
-
nextC = this.
|
|
1017
|
-
if (!
|
|
1066
|
+
nextC = this.code[this.i + 1];
|
|
1067
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart(nextC)) {
|
|
1018
1068
|
break;
|
|
1019
1069
|
}
|
|
1020
1070
|
value += nextC;
|
|
1021
|
-
this.
|
|
1071
|
+
this.i++;
|
|
1072
|
+
}
|
|
1073
|
+
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1074
|
+
this.setToken(TokenType.Dedent, "");
|
|
1075
|
+
return;
|
|
1022
1076
|
}
|
|
1023
1077
|
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
1024
1078
|
this.setToken(TokenType.Identifier, realValue);
|
|
1025
1079
|
}
|
|
1026
1080
|
str(char) {
|
|
1027
|
-
let value =
|
|
1081
|
+
let value = "";
|
|
1028
1082
|
let nextC;
|
|
1029
1083
|
let continuousBackslashCount = 0;
|
|
1030
1084
|
while (1) {
|
|
1031
|
-
nextC = this.
|
|
1032
|
-
value += nextC;
|
|
1085
|
+
nextC = this.code[this.i + 1];
|
|
1033
1086
|
const memoCount = continuousBackslashCount;
|
|
1034
1087
|
if (nextC === "\\") {
|
|
1035
1088
|
continuousBackslashCount++;
|
|
1036
1089
|
} else {
|
|
1037
1090
|
continuousBackslashCount = 0;
|
|
1038
1091
|
}
|
|
1039
|
-
this.
|
|
1092
|
+
this.i++;
|
|
1040
1093
|
if (nextC === char && memoCount % 2 === 0) {
|
|
1041
1094
|
break;
|
|
1042
1095
|
}
|
|
1096
|
+
value += nextC;
|
|
1043
1097
|
}
|
|
1044
|
-
this.setToken(TokenType.Identifier,
|
|
1098
|
+
this.setToken(TokenType.Identifier, value);
|
|
1045
1099
|
}
|
|
1046
1100
|
number(char) {
|
|
1047
1101
|
let value = char;
|
|
1048
1102
|
let nextC;
|
|
1049
1103
|
while (1) {
|
|
1050
|
-
nextC = this.
|
|
1104
|
+
nextC = this.code[this.i + 1];
|
|
1051
1105
|
if (!bobeShared.isNum(nextC)) {
|
|
1052
1106
|
break;
|
|
1053
1107
|
}
|
|
1054
1108
|
value += nextC;
|
|
1055
|
-
this.
|
|
1109
|
+
this.i++;
|
|
1056
1110
|
}
|
|
1057
1111
|
this.setToken(TokenType.Identifier, Number(value));
|
|
1058
1112
|
}
|
|
1059
1113
|
eof() {
|
|
1060
1114
|
this.setToken(TokenType.Eof, "End Of File");
|
|
1061
1115
|
}
|
|
1116
|
+
init(fragments) {
|
|
1117
|
+
if (typeof fragments === "string") {
|
|
1118
|
+
this.setCode(fragments);
|
|
1119
|
+
} else {
|
|
1120
|
+
let code = "";
|
|
1121
|
+
for (let i = 0; i < fragments.length - 1; i++) {
|
|
1122
|
+
const fragment = fragments[i];
|
|
1123
|
+
code += fragment + `${this.HookId}${i}`;
|
|
1124
|
+
}
|
|
1125
|
+
this.setCode(code + fragments[fragments.length - 1]);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1062
1128
|
};
|
|
1063
1129
|
/** Eof 标识符的值 */
|
|
1064
1130
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1131
|
+
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|
|
1065
1132
|
let Tokenizer = _Tokenizer;
|
|
1066
1133
|
|
|
1067
|
-
var __defProp = Object.defineProperty;
|
|
1068
|
-
var __defProps = Object.defineProperties;
|
|
1069
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
1070
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
1071
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
1072
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1073
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1074
|
-
var __spreadValues = (a, b) => {
|
|
1075
|
-
for (var prop in b || (b = {}))
|
|
1076
|
-
if (__hasOwnProp.call(b, prop))
|
|
1077
|
-
__defNormalProp(a, prop, b[prop]);
|
|
1078
|
-
if (__getOwnPropSymbols)
|
|
1079
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
1080
|
-
if (__propIsEnum.call(b, prop))
|
|
1081
|
-
__defNormalProp(a, prop, b[prop]);
|
|
1082
|
-
}
|
|
1083
|
-
return a;
|
|
1084
|
-
};
|
|
1085
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
1086
1134
|
function bobe(fragments, ...values) {
|
|
1087
|
-
const ui = function ui2(
|
|
1088
|
-
const tokenizer = new Tokenizer()
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
return values[i];
|
|
1094
|
-
},
|
|
1095
|
-
setProp(node, key, value, hookI) {
|
|
1096
|
-
node.props[key] = value;
|
|
1097
|
-
}
|
|
1098
|
-
}));
|
|
1099
|
-
cmp.init(Array.from(fragments));
|
|
1100
|
-
return cmp.program(root, before);
|
|
1135
|
+
const ui = function ui2(isSub) {
|
|
1136
|
+
const tokenizer = new Tokenizer(({ i }) => {
|
|
1137
|
+
return values[i];
|
|
1138
|
+
}, isSub);
|
|
1139
|
+
tokenizer.init(Array.from(fragments));
|
|
1140
|
+
return tokenizer;
|
|
1101
1141
|
};
|
|
1102
1142
|
return ui;
|
|
1103
1143
|
}
|
|
1104
1144
|
function customRender(option) {
|
|
1105
1145
|
return function render(Ctor, root) {
|
|
1106
1146
|
const store = Ctor.new();
|
|
1107
|
-
|
|
1147
|
+
const tokenizer = store["ui"](false);
|
|
1148
|
+
const terp = new Interpreter(tokenizer);
|
|
1149
|
+
terp.config(option);
|
|
1150
|
+
const componentNode = {
|
|
1151
|
+
__logicType: FakeType.Component,
|
|
1152
|
+
realParent: root,
|
|
1153
|
+
data: store,
|
|
1154
|
+
tokenizer
|
|
1155
|
+
};
|
|
1156
|
+
terp.program(root, componentNode);
|
|
1157
|
+
return [componentNode, store];
|
|
1108
1158
|
};
|
|
1109
1159
|
}
|
|
1110
1160
|
|