bobe 0.0.48 → 0.0.50
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 +145 -64
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +153 -86
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +154 -87
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +146 -65
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +40 -17
- package/dist/index.umd.js +145 -64
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Queue } from 'bobe-shared';
|
|
2
2
|
import * as aoye from 'aoye';
|
|
3
|
-
import { Store, Effect, effect as effect$1, Scope, Signal, Computed, SignalNode, ValueDiff, CustomEffectOpt } from 'aoye';
|
|
3
|
+
import { Store, Keys, Effect, effect as effect$1, Scope, Signal, Computed, SignalNode, ValueDiff, CustomEffectOpt } from 'aoye';
|
|
4
4
|
export { Store } from 'aoye';
|
|
5
5
|
|
|
6
6
|
declare class Interpreter {
|
|
@@ -27,7 +27,7 @@ declare class Interpreter {
|
|
|
27
27
|
/**
|
|
28
28
|
* 声明部分:
|
|
29
29
|
* 包含首行定义和(可选的)多行属性扩展
|
|
30
|
-
* <declaration> ::= <tagName=token> <
|
|
30
|
+
* <declaration> ::= <tagName=token> <headerLineAndExtensions>
|
|
31
31
|
* */
|
|
32
32
|
declaration(ctx: ProgramCtx): any;
|
|
33
33
|
createContextNode(): ContextNode;
|
|
@@ -49,22 +49,25 @@ declare class Interpreter {
|
|
|
49
49
|
* */
|
|
50
50
|
onePropParsed(data: Store, node: any, key: string, value: any, valueIsMapKey: boolean, isFn: boolean, hookI?: number): void;
|
|
51
51
|
oneRealPropParsed: Interpreter['onePropParsed'];
|
|
52
|
-
componentOrFragmentDeclaration(ComponentOrRender:
|
|
52
|
+
componentOrFragmentDeclaration(ComponentOrRender: UI | typeof Store | InlineFragment, ctx: ProgramCtx): ComponentNode$1;
|
|
53
53
|
getFn(data: any, expression: string | number): any;
|
|
54
54
|
getAssignFn(data: any, expression: string | number): any;
|
|
55
55
|
condDeclaration(ctx: ProgramCtx): IfNode;
|
|
56
56
|
removeLogicNode(node: LogicNode): void;
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
58
|
+
* 首行属性 + 可选的 pipe 扩展行
|
|
59
|
+
* <headerLineAndExtensions> ::= <attributeList> NEWLINE (PIPE <attributeList> NEWLINE)*
|
|
60
60
|
*/
|
|
61
|
-
|
|
61
|
+
headerLineAndExtensions(_node: any): void;
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* 1. 快照
|
|
64
|
+
* 2. 跳过 行内模板片段
|
|
65
|
+
* 3. 准备
|
|
66
|
+
* 1. tokenizer
|
|
67
|
+
* 2. 快照
|
|
68
|
+
* 3. 使用 CtxProvider 中 数据作为 data
|
|
66
69
|
*/
|
|
67
|
-
|
|
70
|
+
inlineFragment(_node: any, snapshot: Partial<Tokenizer>, data: any, key?: string): void;
|
|
68
71
|
/**
|
|
69
72
|
* 属性列表:
|
|
70
73
|
* 可以是空的,或者包含多个属性
|
|
@@ -75,7 +78,7 @@ declare class Interpreter {
|
|
|
75
78
|
* 1. 普通节点 执行 setProps 🪝
|
|
76
79
|
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
77
80
|
*/
|
|
78
|
-
attributeList(_node: any):
|
|
81
|
+
attributeList(_node: any, data: any): string;
|
|
79
82
|
config(opt: TerpConf): void;
|
|
80
83
|
createNode(name: string): {
|
|
81
84
|
name: string;
|
|
@@ -96,6 +99,14 @@ declare class Interpreter {
|
|
|
96
99
|
Effect: typeof Effect;
|
|
97
100
|
effect: typeof effect$1;
|
|
98
101
|
}
|
|
102
|
+
declare class InlineFragment {
|
|
103
|
+
snapshot: Partial<Tokenizer>;
|
|
104
|
+
data: any;
|
|
105
|
+
key: string;
|
|
106
|
+
tokenizer: Tokenizer;
|
|
107
|
+
[Keys.ProxyFreeObject]: boolean;
|
|
108
|
+
constructor(snapshot: Partial<Tokenizer>, data: any, key: string, tokenizer: Tokenizer);
|
|
109
|
+
}
|
|
99
110
|
|
|
100
111
|
interface StackNode<T> {
|
|
101
112
|
value: T;
|
|
@@ -226,9 +237,11 @@ type ProgramCtx = {
|
|
|
226
237
|
before: any;
|
|
227
238
|
};
|
|
228
239
|
/** 返回值是用户自定义的节点 */
|
|
229
|
-
type
|
|
240
|
+
type UI<T = any> = {
|
|
230
241
|
/** 在哪个 Store 声明的 */
|
|
231
242
|
boundStore: Store;
|
|
243
|
+
/** 用户声明片段内可用的 props */
|
|
244
|
+
defineProps?: T;
|
|
232
245
|
(isSub: boolean): Tokenizer;
|
|
233
246
|
};
|
|
234
247
|
type LogicNode = {
|
|
@@ -277,6 +290,10 @@ type FragmentNode$1 = LogicNode & {
|
|
|
277
290
|
};
|
|
278
291
|
type ComponentNode$1 = LogicNode & {
|
|
279
292
|
tokenizer: Tokenizer;
|
|
293
|
+
/** 模版片段快照 */
|
|
294
|
+
fragmentSnapshot?: ReturnType<Tokenizer['snapshot']>;
|
|
295
|
+
/** 渲染模版片段前的 快照,渲染完成后用于恢复 */
|
|
296
|
+
resumeSnapshot?: ReturnType<Tokenizer['snapshot']>;
|
|
280
297
|
};
|
|
281
298
|
type Dep = Signal | Computed | (() => any) | string;
|
|
282
299
|
|
|
@@ -320,19 +337,22 @@ declare class Tokenizer {
|
|
|
320
337
|
/** 当前文件路径 */
|
|
321
338
|
source: string;
|
|
322
339
|
constructor(hook: Hook, useDedentAsEof: boolean);
|
|
340
|
+
initIndentWhenUseDedentAsEof(): void;
|
|
323
341
|
private next;
|
|
324
342
|
getCurrentPos(): Position;
|
|
325
343
|
/** 构造从当前扫描起始位置到模板结尾的 SourceLocation,用于未闭合错误 */
|
|
326
344
|
private unclosedLoc;
|
|
327
345
|
private throwUnclosed;
|
|
328
|
-
resume(_snapshot: ReturnType<Tokenizer['snapshot']>): void;
|
|
329
|
-
snapshot(keys?: (keyof Tokenizer)[]): Partial<Tokenizer>;
|
|
330
|
-
skip(): string;
|
|
346
|
+
resume({ dentStack, waitingTokens, ..._snapshot }: ReturnType<Tokenizer['snapshot']>): void;
|
|
347
|
+
snapshot(keys?: (keyof Tokenizer)[], dtI?: number): Partial<Tokenizer>;
|
|
348
|
+
skip(targetDentLen?: number): string;
|
|
331
349
|
setCode(code: string): void;
|
|
332
350
|
tokenize(): void;
|
|
333
351
|
isEof(): boolean;
|
|
334
352
|
private setToken;
|
|
335
353
|
nextToken(): Token;
|
|
354
|
+
locStart(): void;
|
|
355
|
+
locEnd(): void;
|
|
336
356
|
getComment(): string;
|
|
337
357
|
/**
|
|
338
358
|
* 处理处于行末尾的 comment 例如:
|
|
@@ -428,7 +448,7 @@ interface Property extends BaseNode {
|
|
|
428
448
|
type PropertyValue = StaticValue | DynamicValue;
|
|
429
449
|
interface StaticValue extends BaseNode {
|
|
430
450
|
type: NodeType.StaticValue;
|
|
431
|
-
value: string | number | boolean;
|
|
451
|
+
value: string | number | boolean | TemplateNode[];
|
|
432
452
|
}
|
|
433
453
|
interface PropertyKeyNode extends BaseNode {
|
|
434
454
|
type: NodeType.PropertyKey;
|
|
@@ -503,6 +523,8 @@ declare class Compiler {
|
|
|
503
523
|
*/
|
|
504
524
|
private attributeList;
|
|
505
525
|
parseProperty(node?: Property): Property;
|
|
526
|
+
handleOnlyKeyLoc(node: Property): void;
|
|
527
|
+
handleKeyValueLoc(node: Property): void;
|
|
506
528
|
/**
|
|
507
529
|
* 根据值类型创建属性 key 节点
|
|
508
530
|
*/
|
|
@@ -515,6 +537,7 @@ declare class Compiler {
|
|
|
515
537
|
* 根据值类型创建属性值节点
|
|
516
538
|
*/
|
|
517
539
|
parsePropertyValue(node?: PropertyValue): PropertyValue;
|
|
540
|
+
parsePropertyInlineFragment(node?: PropertyValue): PropertyValue;
|
|
518
541
|
/**
|
|
519
542
|
* 根据值类型创建名称
|
|
520
543
|
*/
|
|
@@ -532,7 +555,7 @@ type ParseHooks = Partial<{
|
|
|
532
555
|
};
|
|
533
556
|
}>;
|
|
534
557
|
|
|
535
|
-
declare function bobe(fragments: TemplateStringsArray, ...values: any[]):
|
|
558
|
+
declare function bobe<T extends Record<any, any> = any>(fragments: TemplateStringsArray, ...values: any[]): UI<T>;
|
|
536
559
|
declare function customRender(option: CustomRenderConf): <T>(Ctor: typeof Store, root: any) => (ComponentNode$1 | Store)[];
|
|
537
560
|
|
|
538
561
|
type IContext = {
|
package/dist/index.umd.js
CHANGED
|
@@ -107,10 +107,13 @@
|
|
|
107
107
|
this.hook = hook;
|
|
108
108
|
this.useDedentAsEof = useDedentAsEof;
|
|
109
109
|
if (useDedentAsEof) {
|
|
110
|
-
this.
|
|
111
|
-
this.isFirstToken = true;
|
|
110
|
+
this.initIndentWhenUseDedentAsEof();
|
|
112
111
|
}
|
|
113
112
|
}
|
|
113
|
+
initIndentWhenUseDedentAsEof() {
|
|
114
|
+
this.setToken(TokenType.Indent, '');
|
|
115
|
+
this.isFirstToken = true;
|
|
116
|
+
}
|
|
114
117
|
next() {
|
|
115
118
|
this.i++;
|
|
116
119
|
}
|
|
@@ -140,16 +143,23 @@
|
|
|
140
143
|
throwUnclosed(code, message, startOffset, startLine, startCol) {
|
|
141
144
|
throw new ParseSyntaxError(code, message, this.unclosedLoc(startOffset, startLine, startCol));
|
|
142
145
|
}
|
|
143
|
-
resume(
|
|
146
|
+
resume({
|
|
147
|
+
dentStack,
|
|
148
|
+
waitingTokens,
|
|
149
|
+
..._snapshot
|
|
150
|
+
}) {
|
|
144
151
|
this.token = undefined;
|
|
145
152
|
this.needIndent = false;
|
|
146
153
|
this.isFirstToken = true;
|
|
147
|
-
this.dentStack = [0];
|
|
154
|
+
this.dentStack = dentStack ? dentStack.slice() : [0];
|
|
155
|
+
if (waitingTokens) {
|
|
156
|
+
this.waitingTokens = waitingTokens.clone();
|
|
157
|
+
}
|
|
148
158
|
Object.assign(this, _snapshot);
|
|
149
159
|
}
|
|
150
|
-
snapshot(keys) {
|
|
160
|
+
snapshot(keys, dtI = 0) {
|
|
151
161
|
const snap = {
|
|
152
|
-
i: this.i,
|
|
162
|
+
i: this.i + dtI,
|
|
153
163
|
waitingTokens: this.waitingTokens.clone()
|
|
154
164
|
};
|
|
155
165
|
if (keys) {
|
|
@@ -162,8 +172,10 @@
|
|
|
162
172
|
}
|
|
163
173
|
return snap;
|
|
164
174
|
}
|
|
165
|
-
skip() {
|
|
166
|
-
|
|
175
|
+
skip(targetDentLen) {
|
|
176
|
+
if (targetDentLen == undefined) {
|
|
177
|
+
targetDentLen = this.dentStack[this.dentStack.length - 1];
|
|
178
|
+
}
|
|
167
179
|
let needIndent = false;
|
|
168
180
|
let skipFragment = ``;
|
|
169
181
|
this.token = undefined;
|
|
@@ -186,7 +198,7 @@
|
|
|
186
198
|
isEmptyLine = _this$getDentValue.isEmptyLine;
|
|
187
199
|
const currLen = value.length;
|
|
188
200
|
if (isEmptyLine) continue;
|
|
189
|
-
if (currLen >
|
|
201
|
+
if (currLen > targetDentLen) {
|
|
190
202
|
skipFragment += value;
|
|
191
203
|
} else {
|
|
192
204
|
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
@@ -199,6 +211,9 @@
|
|
|
199
211
|
break;
|
|
200
212
|
}
|
|
201
213
|
this.dentStack.pop();
|
|
214
|
+
if (expLen > targetDentLen) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
202
217
|
if (!this.token) {
|
|
203
218
|
this.setToken(TokenType.Dedent, String(expLen));
|
|
204
219
|
} else {
|
|
@@ -253,29 +268,31 @@
|
|
|
253
268
|
}
|
|
254
269
|
outer: while (1) {
|
|
255
270
|
if (this.needIndent) {
|
|
271
|
+
this.locStart();
|
|
256
272
|
this.dent();
|
|
273
|
+
this.locEnd();
|
|
257
274
|
} else {
|
|
258
275
|
const char = this.code[this.i];
|
|
259
276
|
switch (char) {
|
|
260
277
|
case '\t':
|
|
261
278
|
case ' ':
|
|
262
279
|
break;
|
|
263
|
-
case '\n':
|
|
264
|
-
this.newLine();
|
|
265
|
-
this.needIndent = true;
|
|
266
|
-
break;
|
|
267
|
-
case '=':
|
|
268
|
-
this.assignment();
|
|
269
|
-
break;
|
|
270
|
-
case '|':
|
|
271
|
-
this.pipe();
|
|
272
|
-
break;
|
|
273
|
-
case ';':
|
|
274
|
-
this.setToken(TokenType.Semicolon, ';');
|
|
275
|
-
break;
|
|
276
280
|
default:
|
|
277
|
-
|
|
281
|
+
this.locStart();
|
|
278
282
|
switch (char) {
|
|
283
|
+
case '\n':
|
|
284
|
+
this.newLine();
|
|
285
|
+
this.needIndent = true;
|
|
286
|
+
break;
|
|
287
|
+
case '=':
|
|
288
|
+
this.assignment();
|
|
289
|
+
break;
|
|
290
|
+
case '|':
|
|
291
|
+
this.pipe();
|
|
292
|
+
break;
|
|
293
|
+
case ';':
|
|
294
|
+
this.setToken(TokenType.Semicolon, ';');
|
|
295
|
+
break;
|
|
279
296
|
case '/':
|
|
280
297
|
this.comment();
|
|
281
298
|
break;
|
|
@@ -300,7 +317,7 @@
|
|
|
300
317
|
}
|
|
301
318
|
break;
|
|
302
319
|
}
|
|
303
|
-
|
|
320
|
+
this.locEnd();
|
|
304
321
|
break;
|
|
305
322
|
}
|
|
306
323
|
this.next();
|
|
@@ -316,6 +333,10 @@
|
|
|
316
333
|
this.handledTokens.push(this.token);
|
|
317
334
|
}
|
|
318
335
|
}
|
|
336
|
+
locStart() {
|
|
337
|
+
}
|
|
338
|
+
locEnd() {
|
|
339
|
+
}
|
|
319
340
|
getComment() {
|
|
320
341
|
let value = '/';
|
|
321
342
|
let nextC = this.code[this.i + 1];
|
|
@@ -332,6 +353,7 @@
|
|
|
332
353
|
this.getComment();
|
|
333
354
|
}
|
|
334
355
|
condExp() {
|
|
356
|
+
this.locStart();
|
|
335
357
|
let value = '';
|
|
336
358
|
this.token = null;
|
|
337
359
|
let char = this.code[this.i];
|
|
@@ -346,12 +368,14 @@
|
|
|
346
368
|
const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
|
|
347
369
|
this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
|
|
348
370
|
this.handledTokens.push(this.token);
|
|
371
|
+
this.locEnd();
|
|
349
372
|
return this.token;
|
|
350
373
|
}
|
|
351
374
|
isEol(i) {
|
|
352
375
|
return this.code[i] === '\n' || this.code[i] === '/';
|
|
353
376
|
}
|
|
354
377
|
jsExp() {
|
|
378
|
+
this.locStart();
|
|
355
379
|
this.token = null;
|
|
356
380
|
let value = '';
|
|
357
381
|
let char = this.code[this.i];
|
|
@@ -365,6 +389,7 @@
|
|
|
365
389
|
}
|
|
366
390
|
this.setToken(TokenType.Identifier, value, 0);
|
|
367
391
|
this.handledTokens.push(this.token);
|
|
392
|
+
this.locEnd();
|
|
368
393
|
return this.token;
|
|
369
394
|
}
|
|
370
395
|
peekChar() {
|
|
@@ -552,7 +577,7 @@
|
|
|
552
577
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
553
578
|
if (currLen > prevLen) {
|
|
554
579
|
this.dentStack.push(currLen);
|
|
555
|
-
this.setToken(TokenType.Indent, currLen);
|
|
580
|
+
this.setToken(TokenType.Indent, currLen, 0);
|
|
556
581
|
return indentHasLen;
|
|
557
582
|
}
|
|
558
583
|
if (currLen < prevLen) {
|
|
@@ -567,7 +592,7 @@
|
|
|
567
592
|
}
|
|
568
593
|
this.dentStack.pop();
|
|
569
594
|
if (!this.token) {
|
|
570
|
-
this.setToken(TokenType.Dedent, String(expLen));
|
|
595
|
+
this.setToken(TokenType.Dedent, String(expLen), 0);
|
|
571
596
|
} else {
|
|
572
597
|
this.waitingTokens.push({
|
|
573
598
|
type: TokenType.Dedent,
|
|
@@ -976,7 +1001,7 @@
|
|
|
976
1001
|
let _initProto;
|
|
977
1002
|
class Compiler {
|
|
978
1003
|
static {
|
|
979
|
-
var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
|
|
1004
|
+
var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, NodeLoc], 2, "parsePropertyInlineFragment"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
|
|
980
1005
|
_initProto = _applyDecs$e[0];
|
|
981
1006
|
}
|
|
982
1007
|
errors = (_initProto(this), []);
|
|
@@ -1078,9 +1103,9 @@
|
|
|
1078
1103
|
parseComponentNode(node) {
|
|
1079
1104
|
const name = this.parseName();
|
|
1080
1105
|
this.tokenizer.nextToken();
|
|
1081
|
-
const props = this.headerLineAndExtensions();
|
|
1082
1106
|
node.type = NodeType.Component;
|
|
1083
1107
|
node.componentName = name;
|
|
1108
|
+
const props = this.headerLineAndExtensions();
|
|
1084
1109
|
node.props = props;
|
|
1085
1110
|
this.hooks.parseComponentNode?.propsAdded?.call(this, node);
|
|
1086
1111
|
const children = this.handleChildren();
|
|
@@ -1098,9 +1123,9 @@
|
|
|
1098
1123
|
}
|
|
1099
1124
|
const tagName = tagToken.value;
|
|
1100
1125
|
this.tokenizer.nextToken();
|
|
1101
|
-
const props = this.headerLineAndExtensions();
|
|
1102
1126
|
node.type = NodeType.Element;
|
|
1103
1127
|
node.tagName = tagName;
|
|
1128
|
+
const props = this.headerLineAndExtensions();
|
|
1104
1129
|
node.props = props;
|
|
1105
1130
|
this.hooks.parseElementNode?.propsAdded?.call(this, node);
|
|
1106
1131
|
const children = this.handleChildren();
|
|
@@ -1174,17 +1199,17 @@
|
|
|
1174
1199
|
}
|
|
1175
1200
|
headerLineAndExtensions() {
|
|
1176
1201
|
const props = [];
|
|
1177
|
-
|
|
1178
|
-
if (this.tokenizer.token.type & TokenType.NewLine) {
|
|
1179
|
-
this.tokenizer.nextToken();
|
|
1180
|
-
}
|
|
1181
|
-
while (this.tokenizer.token.type & TokenType.Pipe) {
|
|
1182
|
-
this.tokenizer.nextToken();
|
|
1202
|
+
do {
|
|
1183
1203
|
props.push(...this.attributeList());
|
|
1184
1204
|
if (this.tokenizer.token.type & TokenType.NewLine) {
|
|
1185
1205
|
this.tokenizer.nextToken();
|
|
1186
1206
|
}
|
|
1187
|
-
|
|
1207
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
1208
|
+
break;
|
|
1209
|
+
} else {
|
|
1210
|
+
this.tokenizer.nextToken();
|
|
1211
|
+
}
|
|
1212
|
+
} while (true);
|
|
1188
1213
|
return props;
|
|
1189
1214
|
}
|
|
1190
1215
|
attributeList() {
|
|
@@ -1208,25 +1233,35 @@
|
|
|
1208
1233
|
const token = this.tokenizer.nextToken();
|
|
1209
1234
|
if (token.value !== '=') {
|
|
1210
1235
|
this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1211
|
-
|
|
1212
|
-
node.loc.end = node.key.loc.end;
|
|
1213
|
-
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1236
|
+
this.handleOnlyKeyLoc(node);
|
|
1214
1237
|
return node;
|
|
1215
1238
|
}
|
|
1216
1239
|
const valueToken = this.tokenizer.nextToken();
|
|
1240
|
+
if (valueToken.type & TokenType.NewLine) {
|
|
1241
|
+
this.tokenizer.nextToken();
|
|
1242
|
+
node.value = this.parsePropertyInlineFragment();
|
|
1243
|
+
this.handleKeyValueLoc(node);
|
|
1244
|
+
return node;
|
|
1245
|
+
}
|
|
1217
1246
|
if ((valueToken.type & ValueTokenType) === 0) {
|
|
1218
1247
|
this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1219
|
-
|
|
1220
|
-
node.loc.end = node.key.loc.end;
|
|
1221
|
-
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1248
|
+
this.handleOnlyKeyLoc(node);
|
|
1222
1249
|
return node;
|
|
1223
1250
|
}
|
|
1224
1251
|
node.value = this.parsePropertyValue();
|
|
1225
1252
|
this.tokenizer.nextToken();
|
|
1253
|
+
this.handleKeyValueLoc(node);
|
|
1254
|
+
return node;
|
|
1255
|
+
}
|
|
1256
|
+
handleOnlyKeyLoc(node) {
|
|
1257
|
+
node.loc.start = node.key.loc.start;
|
|
1258
|
+
node.loc.end = node.key.loc.end;
|
|
1259
|
+
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1260
|
+
}
|
|
1261
|
+
handleKeyValueLoc(node) {
|
|
1226
1262
|
node.loc.start = node.key.loc.start;
|
|
1227
1263
|
node.loc.end = node.value.loc.end;
|
|
1228
1264
|
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1229
|
-
return node;
|
|
1230
1265
|
}
|
|
1231
1266
|
parsePropertyKey(node) {
|
|
1232
1267
|
node.type = NodeType.PropertyKey;
|
|
@@ -1251,6 +1286,12 @@
|
|
|
1251
1286
|
node.value = value;
|
|
1252
1287
|
return node;
|
|
1253
1288
|
}
|
|
1289
|
+
parsePropertyInlineFragment(node) {
|
|
1290
|
+
const list = this.handleChildren();
|
|
1291
|
+
node.type = NodeType.StaticValue;
|
|
1292
|
+
node.value = list;
|
|
1293
|
+
return node;
|
|
1294
|
+
}
|
|
1254
1295
|
parseName(node) {
|
|
1255
1296
|
const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
|
|
1256
1297
|
_this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
|
|
@@ -1474,6 +1515,9 @@
|
|
|
1474
1515
|
}
|
|
1475
1516
|
if (sort & NodeSort.TokenizerSwitcher) {
|
|
1476
1517
|
const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
|
|
1518
|
+
if (parent.resumeSnapshot) {
|
|
1519
|
+
this.tokenizer.resume(parent.resumeSnapshot);
|
|
1520
|
+
}
|
|
1477
1521
|
this.tokenizer = switcher.tokenizer;
|
|
1478
1522
|
}
|
|
1479
1523
|
if (parent.__logicType === FakeType.ForItem) {
|
|
@@ -1568,7 +1612,7 @@
|
|
|
1568
1612
|
} else {
|
|
1569
1613
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
1570
1614
|
const val = data[aoye.Keys.Raw][value];
|
|
1571
|
-
if (typeof val === 'function') {
|
|
1615
|
+
if (typeof val === 'function' || val instanceof InlineFragment) {
|
|
1572
1616
|
_node = this.componentOrFragmentDeclaration(val, ctx);
|
|
1573
1617
|
} else {
|
|
1574
1618
|
const str = valueIsMapKey ? value : this.getFn(data, value);
|
|
@@ -1580,11 +1624,15 @@
|
|
|
1580
1624
|
_node = this.createNode(value);
|
|
1581
1625
|
}
|
|
1582
1626
|
this.tokenizer.nextToken();
|
|
1583
|
-
this.
|
|
1584
|
-
this.extensionLines(_node);
|
|
1627
|
+
this.headerLineAndExtensions(_node);
|
|
1585
1628
|
this.onePropParsed = this.oneRealPropParsed;
|
|
1586
1629
|
if (_node.__logicType & TokenizerSwitcherBit) {
|
|
1587
1630
|
this.tokenizer = _node.tokenizer;
|
|
1631
|
+
if (_node.fragmentSnapshot) {
|
|
1632
|
+
this.tokenizer.resume(_node.fragmentSnapshot);
|
|
1633
|
+
this.tokenizer.useDedentAsEof = true;
|
|
1634
|
+
this.tokenizer.initIndentWhenUseDedentAsEof();
|
|
1635
|
+
}
|
|
1588
1636
|
}
|
|
1589
1637
|
return _node;
|
|
1590
1638
|
}
|
|
@@ -1960,16 +2008,25 @@
|
|
|
1960
2008
|
}
|
|
1961
2009
|
oneRealPropParsed = this.onePropParsed.bind(this);
|
|
1962
2010
|
componentOrFragmentDeclaration(ComponentOrRender, ctx) {
|
|
1963
|
-
let Component,
|
|
2011
|
+
let Component, tokenizer, child, fragmentSnapshot, resumeSnapshot;
|
|
1964
2012
|
const isCC = ComponentOrRender.prototype instanceof aoye.Store;
|
|
1965
2013
|
if (isCC) {
|
|
1966
2014
|
Component = ComponentOrRender;
|
|
1967
2015
|
child = Component.new();
|
|
2016
|
+
tokenizer = child.ui(true);
|
|
2017
|
+
} else if (ComponentOrRender instanceof InlineFragment) {
|
|
2018
|
+
const conf = ComponentOrRender;
|
|
2019
|
+
child = aoye.deepSignal({}, aoye.getPulling(), true);
|
|
2020
|
+
Object.setPrototypeOf(child, conf.data);
|
|
2021
|
+
tokenizer = conf.tokenizer;
|
|
2022
|
+
fragmentSnapshot = conf.snapshot;
|
|
2023
|
+
resumeSnapshot = tokenizer.snapshot(['token', 'needIndent', 'isFirstToken', 'dentStack', 'isFirstToken', 'useDedentAsEof']);
|
|
1968
2024
|
} else {
|
|
1969
|
-
render = ComponentOrRender;
|
|
2025
|
+
const render = ComponentOrRender;
|
|
1970
2026
|
const boundStore = render.boundStore;
|
|
1971
2027
|
child = aoye.deepSignal({}, aoye.getPulling(), true);
|
|
1972
2028
|
Object.setPrototypeOf(child, boundStore);
|
|
2029
|
+
tokenizer = render(true);
|
|
1973
2030
|
}
|
|
1974
2031
|
const node = {
|
|
1975
2032
|
__logicType: isCC ? FakeType.Component : FakeType.Fragment,
|
|
@@ -1977,7 +2034,9 @@
|
|
|
1977
2034
|
realBefore: null,
|
|
1978
2035
|
realAfter: null,
|
|
1979
2036
|
data: child,
|
|
1980
|
-
tokenizer
|
|
2037
|
+
tokenizer,
|
|
2038
|
+
fragmentSnapshot,
|
|
2039
|
+
resumeSnapshot
|
|
1981
2040
|
};
|
|
1982
2041
|
this.onePropParsed = createStoreOnePropParsed(child);
|
|
1983
2042
|
node.realAfter = this.insertAfterAnchor('component-after');
|
|
@@ -2114,26 +2173,38 @@
|
|
|
2114
2173
|
point = next;
|
|
2115
2174
|
}
|
|
2116
2175
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2176
|
+
headerLineAndExtensions(_node) {
|
|
2177
|
+
const tokenizer = this.tokenizer;
|
|
2178
|
+
do {
|
|
2179
|
+
const isComponent = _node.__logicType & TokenizerSwitcherBit;
|
|
2180
|
+
let snapshot, dentLen;
|
|
2181
|
+
const data = this.getData();
|
|
2182
|
+
const unHandledKey = this.attributeList(_node, data);
|
|
2183
|
+
if (isComponent) {
|
|
2184
|
+
snapshot = tokenizer.snapshot(undefined, -1);
|
|
2185
|
+
dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
|
|
2121
2186
|
}
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2187
|
+
tokenizer.nextToken();
|
|
2188
|
+
if ((tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
2189
|
+
if (isComponent && tokenizer.token.type & TokenType.Indent) {
|
|
2190
|
+
this.inlineFragment(_node, snapshot, data, unHandledKey);
|
|
2191
|
+
tokenizer.skip(dentLen);
|
|
2192
|
+
if ((tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
2193
|
+
break;
|
|
2194
|
+
}
|
|
2195
|
+
} else {
|
|
2196
|
+
break;
|
|
2197
|
+
}
|
|
2126
2198
|
}
|
|
2127
|
-
|
|
2128
|
-
}
|
|
2199
|
+
tokenizer.nextToken();
|
|
2200
|
+
} while (true);
|
|
2129
2201
|
}
|
|
2130
|
-
|
|
2131
|
-
this.
|
|
2132
|
-
this.
|
|
2202
|
+
inlineFragment(_node, snapshot, data, key = 'children') {
|
|
2203
|
+
const value = new InlineFragment(snapshot, data, key, this.tokenizer);
|
|
2204
|
+
this.onePropParsed(data, _node, key, value, false, true);
|
|
2133
2205
|
}
|
|
2134
|
-
attributeList(_node) {
|
|
2206
|
+
attributeList(_node, data) {
|
|
2135
2207
|
let key, eq;
|
|
2136
|
-
const data = this.getData();
|
|
2137
2208
|
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
2138
2209
|
if (key == null) {
|
|
2139
2210
|
key = this.tokenizer.token.value;
|
|
@@ -2181,6 +2252,7 @@
|
|
|
2181
2252
|
}
|
|
2182
2253
|
this.tokenizer.nextToken();
|
|
2183
2254
|
}
|
|
2255
|
+
return key;
|
|
2184
2256
|
}
|
|
2185
2257
|
config(opt) {
|
|
2186
2258
|
Object.assign(this, opt);
|
|
@@ -2264,6 +2336,15 @@
|
|
|
2264
2336
|
};
|
|
2265
2337
|
return onePropParsed;
|
|
2266
2338
|
}
|
|
2339
|
+
class InlineFragment {
|
|
2340
|
+
[aoye.Keys.ProxyFreeObject] = true;
|
|
2341
|
+
constructor(snapshot, data, key, tokenizer) {
|
|
2342
|
+
this.snapshot = snapshot;
|
|
2343
|
+
this.data = data;
|
|
2344
|
+
this.key = key;
|
|
2345
|
+
this.tokenizer = tokenizer;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2267
2348
|
|
|
2268
2349
|
function bobe(fragments, ...values) {
|
|
2269
2350
|
const ui = function ui(isSub) {
|