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