bobe 0.0.48 → 0.0.49

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 CHANGED
@@ -106,10 +106,13 @@ class Tokenizer {
106
106
  this.hook = hook;
107
107
  this.useDedentAsEof = useDedentAsEof;
108
108
  if (useDedentAsEof) {
109
- this.setToken(TokenType.Indent, '');
110
- this.isFirstToken = true;
109
+ this.initIndentWhenUseDedentAsEof();
111
110
  }
112
111
  }
112
+ initIndentWhenUseDedentAsEof() {
113
+ this.setToken(TokenType.Indent, '');
114
+ this.isFirstToken = true;
115
+ }
113
116
  next() {
114
117
  this.i++;
115
118
  }
@@ -139,16 +142,23 @@ class Tokenizer {
139
142
  throwUnclosed(code, message, startOffset, startLine, startCol) {
140
143
  throw new ParseSyntaxError(code, message, this.unclosedLoc(startOffset, startLine, startCol));
141
144
  }
142
- resume(_snapshot) {
145
+ resume({
146
+ dentStack,
147
+ waitingTokens,
148
+ ..._snapshot
149
+ }) {
143
150
  this.token = undefined;
144
151
  this.needIndent = false;
145
152
  this.isFirstToken = true;
146
- this.dentStack = [0];
153
+ this.dentStack = dentStack ? dentStack.slice() : [0];
154
+ if (waitingTokens) {
155
+ this.waitingTokens = waitingTokens.clone();
156
+ }
147
157
  Object.assign(this, _snapshot);
148
158
  }
149
- snapshot(keys) {
159
+ snapshot(keys, dtI = 0) {
150
160
  const snap = {
151
- i: this.i,
161
+ i: this.i + dtI,
152
162
  waitingTokens: this.waitingTokens.clone()
153
163
  };
154
164
  if (keys) {
@@ -161,8 +171,10 @@ class Tokenizer {
161
171
  }
162
172
  return snap;
163
173
  }
164
- skip() {
165
- const logicDentLen = this.dentStack[this.dentStack.length - 1];
174
+ skip(targetDentLen) {
175
+ if (targetDentLen == undefined) {
176
+ targetDentLen = this.dentStack[this.dentStack.length - 1];
177
+ }
166
178
  let needIndent = false;
167
179
  let skipFragment = ``;
168
180
  this.token = undefined;
@@ -185,7 +197,7 @@ class Tokenizer {
185
197
  isEmptyLine = _this$getDentValue.isEmptyLine;
186
198
  const currLen = value.length;
187
199
  if (isEmptyLine) continue;
188
- if (currLen > logicDentLen) {
200
+ if (currLen > targetDentLen) {
189
201
  skipFragment += value;
190
202
  } else {
191
203
  for (let i = this.dentStack.length - 1; i >= 0; i--) {
@@ -198,6 +210,9 @@ class Tokenizer {
198
210
  break;
199
211
  }
200
212
  this.dentStack.pop();
213
+ if (expLen > targetDentLen) {
214
+ continue;
215
+ }
201
216
  if (!this.token) {
202
217
  this.setToken(TokenType.Dedent, String(expLen));
203
218
  } else {
@@ -252,29 +267,31 @@ class Tokenizer {
252
267
  }
253
268
  outer: while (1) {
254
269
  if (this.needIndent) {
270
+ this.locStart();
255
271
  this.dent();
272
+ this.locEnd();
256
273
  } else {
257
274
  const char = this.code[this.i];
258
275
  switch (char) {
259
276
  case '\t':
260
277
  case ' ':
261
278
  break;
262
- case '\n':
263
- this.newLine();
264
- this.needIndent = true;
265
- break;
266
- case '=':
267
- this.assignment();
268
- break;
269
- case '|':
270
- this.pipe();
271
- break;
272
- case ';':
273
- this.setToken(TokenType.Semicolon, ';');
274
- break;
275
279
  default:
276
- if (false) ;
280
+ this.locStart();
277
281
  switch (char) {
282
+ case '\n':
283
+ this.newLine();
284
+ this.needIndent = true;
285
+ break;
286
+ case '=':
287
+ this.assignment();
288
+ break;
289
+ case '|':
290
+ this.pipe();
291
+ break;
292
+ case ';':
293
+ this.setToken(TokenType.Semicolon, ';');
294
+ break;
278
295
  case '/':
279
296
  this.comment();
280
297
  break;
@@ -299,7 +316,7 @@ class Tokenizer {
299
316
  }
300
317
  break;
301
318
  }
302
- if (false) ;
319
+ this.locEnd();
303
320
  break;
304
321
  }
305
322
  this.next();
@@ -315,6 +332,10 @@ class Tokenizer {
315
332
  this.handledTokens.push(this.token);
316
333
  }
317
334
  }
335
+ locStart() {
336
+ }
337
+ locEnd() {
338
+ }
318
339
  getComment() {
319
340
  let value = '/';
320
341
  let nextC = this.code[this.i + 1];
@@ -331,6 +352,7 @@ class Tokenizer {
331
352
  this.getComment();
332
353
  }
333
354
  condExp() {
355
+ this.locStart();
334
356
  let value = '';
335
357
  this.token = null;
336
358
  let char = this.code[this.i];
@@ -345,12 +367,14 @@ class Tokenizer {
345
367
  const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
346
368
  this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
347
369
  this.handledTokens.push(this.token);
370
+ this.locEnd();
348
371
  return this.token;
349
372
  }
350
373
  isEol(i) {
351
374
  return this.code[i] === '\n' || this.code[i] === '/';
352
375
  }
353
376
  jsExp() {
377
+ this.locStart();
354
378
  this.token = null;
355
379
  let value = '';
356
380
  let char = this.code[this.i];
@@ -364,6 +388,7 @@ class Tokenizer {
364
388
  }
365
389
  this.setToken(TokenType.Identifier, value, 0);
366
390
  this.handledTokens.push(this.token);
391
+ this.locEnd();
367
392
  return this.token;
368
393
  }
369
394
  peekChar() {
@@ -551,7 +576,7 @@ class Tokenizer {
551
576
  const prevLen = this.dentStack[this.dentStack.length - 1];
552
577
  if (currLen > prevLen) {
553
578
  this.dentStack.push(currLen);
554
- this.setToken(TokenType.Indent, currLen);
579
+ this.setToken(TokenType.Indent, currLen, 0);
555
580
  return indentHasLen;
556
581
  }
557
582
  if (currLen < prevLen) {
@@ -566,7 +591,7 @@ class Tokenizer {
566
591
  }
567
592
  this.dentStack.pop();
568
593
  if (!this.token) {
569
- this.setToken(TokenType.Dedent, String(expLen));
594
+ this.setToken(TokenType.Dedent, String(expLen), 0);
570
595
  } else {
571
596
  this.waitingTokens.push({
572
597
  type: TokenType.Dedent,
@@ -975,7 +1000,7 @@ var NodeType = function (NodeType) {
975
1000
  let _initProto;
976
1001
  class Compiler {
977
1002
  static {
978
- 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);
1003
+ 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);
979
1004
  _initProto = _applyDecs$e[0];
980
1005
  }
981
1006
  errors = (_initProto(this), []);
@@ -1077,9 +1102,9 @@ class Compiler {
1077
1102
  parseComponentNode(node) {
1078
1103
  const name = this.parseName();
1079
1104
  this.tokenizer.nextToken();
1080
- const props = this.headerLineAndExtensions();
1081
1105
  node.type = NodeType.Component;
1082
1106
  node.componentName = name;
1107
+ const props = this.headerLineAndExtensions();
1083
1108
  node.props = props;
1084
1109
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
1085
1110
  const children = this.handleChildren();
@@ -1097,9 +1122,9 @@ class Compiler {
1097
1122
  }
1098
1123
  const tagName = tagToken.value;
1099
1124
  this.tokenizer.nextToken();
1100
- const props = this.headerLineAndExtensions();
1101
1125
  node.type = NodeType.Element;
1102
1126
  node.tagName = tagName;
1127
+ const props = this.headerLineAndExtensions();
1103
1128
  node.props = props;
1104
1129
  this.hooks.parseElementNode?.propsAdded?.call(this, node);
1105
1130
  const children = this.handleChildren();
@@ -1173,17 +1198,17 @@ class Compiler {
1173
1198
  }
1174
1199
  headerLineAndExtensions() {
1175
1200
  const props = [];
1176
- props.push(...this.attributeList());
1177
- if (this.tokenizer.token.type & TokenType.NewLine) {
1178
- this.tokenizer.nextToken();
1179
- }
1180
- while (this.tokenizer.token.type & TokenType.Pipe) {
1181
- this.tokenizer.nextToken();
1201
+ do {
1182
1202
  props.push(...this.attributeList());
1183
1203
  if (this.tokenizer.token.type & TokenType.NewLine) {
1184
1204
  this.tokenizer.nextToken();
1185
1205
  }
1186
- }
1206
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1207
+ break;
1208
+ } else {
1209
+ this.tokenizer.nextToken();
1210
+ }
1211
+ } while (true);
1187
1212
  return props;
1188
1213
  }
1189
1214
  attributeList() {
@@ -1207,25 +1232,35 @@ class Compiler {
1207
1232
  const token = this.tokenizer.nextToken();
1208
1233
  if (token.value !== '=') {
1209
1234
  this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
1210
- node.loc.start = node.key.loc.start;
1211
- node.loc.end = node.key.loc.end;
1212
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1235
+ this.handleOnlyKeyLoc(node);
1213
1236
  return node;
1214
1237
  }
1215
1238
  const valueToken = this.tokenizer.nextToken();
1239
+ if (valueToken.type & TokenType.NewLine) {
1240
+ this.tokenizer.nextToken();
1241
+ node.value = this.parsePropertyInlineFragment();
1242
+ this.handleKeyValueLoc(node);
1243
+ return node;
1244
+ }
1216
1245
  if ((valueToken.type & ValueTokenType) === 0) {
1217
1246
  this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
1218
- node.loc.start = node.key.loc.start;
1219
- node.loc.end = node.key.loc.end;
1220
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1247
+ this.handleOnlyKeyLoc(node);
1221
1248
  return node;
1222
1249
  }
1223
1250
  node.value = this.parsePropertyValue();
1224
1251
  this.tokenizer.nextToken();
1252
+ this.handleKeyValueLoc(node);
1253
+ return node;
1254
+ }
1255
+ handleOnlyKeyLoc(node) {
1256
+ node.loc.start = node.key.loc.start;
1257
+ node.loc.end = node.key.loc.end;
1258
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1259
+ }
1260
+ handleKeyValueLoc(node) {
1225
1261
  node.loc.start = node.key.loc.start;
1226
1262
  node.loc.end = node.value.loc.end;
1227
1263
  node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1228
- return node;
1229
1264
  }
1230
1265
  parsePropertyKey(node) {
1231
1266
  node.type = NodeType.PropertyKey;
@@ -1250,6 +1285,12 @@ class Compiler {
1250
1285
  node.value = value;
1251
1286
  return node;
1252
1287
  }
1288
+ parsePropertyInlineFragment(node) {
1289
+ const list = this.handleChildren();
1290
+ node.type = NodeType.StaticValue;
1291
+ node.value = list;
1292
+ return node;
1293
+ }
1253
1294
  parseName(node) {
1254
1295
  const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
1255
1296
  _this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
@@ -1473,6 +1514,9 @@ class Interpreter {
1473
1514
  }
1474
1515
  if (sort & NodeSort.TokenizerSwitcher) {
1475
1516
  const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1517
+ if (parent.resumeSnapshot) {
1518
+ this.tokenizer.resume(parent.resumeSnapshot);
1519
+ }
1476
1520
  this.tokenizer = switcher.tokenizer;
1477
1521
  }
1478
1522
  if (parent.__logicType === FakeType.ForItem) {
@@ -1567,7 +1611,7 @@ class Interpreter {
1567
1611
  } else {
1568
1612
  const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1569
1613
  const val = data[aoye.Keys.Raw][value];
1570
- if (typeof val === 'function') {
1614
+ if (typeof val === 'function' || val instanceof InlineFragment) {
1571
1615
  _node = this.componentOrFragmentDeclaration(val, ctx);
1572
1616
  } else {
1573
1617
  const str = valueIsMapKey ? value : this.getFn(data, value);
@@ -1579,11 +1623,15 @@ class Interpreter {
1579
1623
  _node = this.createNode(value);
1580
1624
  }
1581
1625
  this.tokenizer.nextToken();
1582
- this.headerLine(_node);
1583
- this.extensionLines(_node);
1626
+ this.headerLineAndExtensions(_node);
1584
1627
  this.onePropParsed = this.oneRealPropParsed;
1585
1628
  if (_node.__logicType & TokenizerSwitcherBit) {
1586
1629
  this.tokenizer = _node.tokenizer;
1630
+ if (_node.fragmentSnapshot) {
1631
+ this.tokenizer.resume(_node.fragmentSnapshot);
1632
+ this.tokenizer.useDedentAsEof = true;
1633
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1634
+ }
1587
1635
  }
1588
1636
  return _node;
1589
1637
  }
@@ -1959,16 +2007,25 @@ class Interpreter {
1959
2007
  }
1960
2008
  oneRealPropParsed = this.onePropParsed.bind(this);
1961
2009
  componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1962
- let Component, render, child;
2010
+ let Component, tokenizer, child, fragmentSnapshot, resumeSnapshot;
1963
2011
  const isCC = ComponentOrRender.prototype instanceof aoye.Store;
1964
2012
  if (isCC) {
1965
2013
  Component = ComponentOrRender;
1966
2014
  child = Component.new();
2015
+ tokenizer = child.ui(true);
2016
+ } else if (ComponentOrRender instanceof InlineFragment) {
2017
+ const conf = ComponentOrRender;
2018
+ child = aoye.deepSignal({}, aoye.getPulling(), true);
2019
+ Object.setPrototypeOf(child, conf.data);
2020
+ tokenizer = conf.tokenizer;
2021
+ fragmentSnapshot = conf.snapshot;
2022
+ resumeSnapshot = tokenizer.snapshot(['token', 'needIndent', 'isFirstToken', 'dentStack', 'isFirstToken', 'useDedentAsEof']);
1967
2023
  } else {
1968
- render = ComponentOrRender;
2024
+ const render = ComponentOrRender;
1969
2025
  const boundStore = render.boundStore;
1970
2026
  child = aoye.deepSignal({}, aoye.getPulling(), true);
1971
2027
  Object.setPrototypeOf(child, boundStore);
2028
+ tokenizer = render(true);
1972
2029
  }
1973
2030
  const node = {
1974
2031
  __logicType: isCC ? FakeType.Component : FakeType.Fragment,
@@ -1976,7 +2033,9 @@ class Interpreter {
1976
2033
  realBefore: null,
1977
2034
  realAfter: null,
1978
2035
  data: child,
1979
- tokenizer: render ? render(true) : child.ui(true)
2036
+ tokenizer,
2037
+ fragmentSnapshot,
2038
+ resumeSnapshot
1980
2039
  };
1981
2040
  this.onePropParsed = createStoreOnePropParsed(child);
1982
2041
  node.realAfter = this.insertAfterAnchor('component-after');
@@ -2113,26 +2172,38 @@ class Interpreter {
2113
2172
  point = next;
2114
2173
  }
2115
2174
  }
2116
- extensionLines(_node) {
2117
- while (1) {
2118
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
2119
- return;
2175
+ headerLineAndExtensions(_node) {
2176
+ const tokenizer = this.tokenizer;
2177
+ do {
2178
+ const isComponent = _node.__logicType & TokenizerSwitcherBit;
2179
+ let snapshot, dentLen;
2180
+ const data = this.getData();
2181
+ const unHandledKey = this.attributeList(_node, data);
2182
+ if (isComponent) {
2183
+ snapshot = tokenizer.snapshot(undefined, -1);
2184
+ dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
2120
2185
  }
2121
- this.tokenizer.nextToken();
2122
- this.attributeList(_node);
2123
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2124
- return;
2186
+ tokenizer.nextToken();
2187
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2188
+ if (isComponent && tokenizer.token.type & TokenType.Indent) {
2189
+ this.inlineFragment(_node, snapshot, data, unHandledKey);
2190
+ tokenizer.skip(dentLen);
2191
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2192
+ break;
2193
+ }
2194
+ } else {
2195
+ break;
2196
+ }
2125
2197
  }
2126
- this.tokenizer.nextToken();
2127
- }
2198
+ tokenizer.nextToken();
2199
+ } while (true);
2128
2200
  }
2129
- headerLine(_node) {
2130
- this.attributeList(_node);
2131
- this.tokenizer.nextToken();
2201
+ inlineFragment(_node, snapshot, data, key = 'children') {
2202
+ const value = new InlineFragment(snapshot, data, key, this.tokenizer);
2203
+ this.onePropParsed(data, _node, key, value, false, true);
2132
2204
  }
2133
- attributeList(_node) {
2205
+ attributeList(_node, data) {
2134
2206
  let key, eq;
2135
- const data = this.getData();
2136
2207
  while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2137
2208
  if (key == null) {
2138
2209
  key = this.tokenizer.token.value;
@@ -2180,6 +2251,7 @@ class Interpreter {
2180
2251
  }
2181
2252
  this.tokenizer.nextToken();
2182
2253
  }
2254
+ return key;
2183
2255
  }
2184
2256
  config(opt) {
2185
2257
  Object.assign(this, opt);
@@ -2263,6 +2335,15 @@ function createStoreOnePropParsed(child) {
2263
2335
  };
2264
2336
  return onePropParsed;
2265
2337
  }
2338
+ class InlineFragment {
2339
+ [aoye.Keys.ProxyFreeObject] = true;
2340
+ constructor(snapshot, data, key, tokenizer) {
2341
+ this.snapshot = snapshot;
2342
+ this.data = data;
2343
+ this.key = key;
2344
+ this.tokenizer = tokenizer;
2345
+ }
2346
+ }
2266
2347
 
2267
2348
  function bobe(fragments, ...values) {
2268
2349
  const ui = function ui(isSub) {