bobe 0.0.37 → 0.0.38

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/index.d.ts CHANGED
@@ -133,7 +133,12 @@ declare enum TokenType {
133
133
  InsertionExp = 128,
134
134
  Semicolon = 256,
135
135
  /** 仅编译时可解析 */
136
- StaticInsExp = 512
136
+ StaticInsExp = 512,
137
+ String = 1024,
138
+ Number = 2048,
139
+ Boolean = 4096,
140
+ Null = 8192,
141
+ Undefined = 16384
137
142
  }
138
143
  declare enum FakeType {
139
144
  If = 1,
@@ -182,13 +187,15 @@ declare enum ParseErrorCode {
182
187
  INDENT_MISMATCH = 9005,
183
188
  MISSING_ASSIGN = 9006,
184
189
  INVALID_TAG_NAME = 9007,
185
- ELSE_WITHOUT_IF = 9008,
186
- EMPTY_IF_BODY = 9009,
187
- EMPTY_FOR_BODY = 9010,
188
- MISSING_FOR_COLLECTION = 9011,
189
- MISSING_FOR_SEMICOLON = 9012,
190
- MISSING_FOR_ITEM = 9013,
191
- PIPE_IN_WRONG_CONTEXT = 9014
190
+ INVALID_PROP_KEY = 9008,
191
+ ELSE_WITHOUT_IF = 9009,
192
+ EMPTY_IF_BODY = 9010,
193
+ EMPTY_FOR_BODY = 9011,
194
+ MISSING_FOR_COLLECTION = 9012,
195
+ MISSING_FOR_SEMICOLON = 9013,
196
+ MISSING_FOR_ITEM = 9014,
197
+ MISSING_PROP_ASSIGNMENT = 9015,
198
+ PIPE_IN_WRONG_CONTEXT = 9016
192
199
  }
193
200
  type ParseError = {
194
201
  code: ParseErrorCode;
@@ -360,6 +367,7 @@ type ASTNodeType = NodeType;
360
367
  interface BaseNode {
361
368
  type: ASTNodeType;
362
369
  loc?: SourceLocation;
370
+ hasError?: boolean;
363
371
  }
364
372
  interface Program extends BaseNode {
365
373
  type: NodeType.Program;
@@ -467,6 +475,10 @@ declare class Compiler {
467
475
  * 根据值类型创建属性 key 节点
468
476
  */
469
477
  parsePropertyKey(node?: PropertyKeyNode): PropertyKeyNode;
478
+ /**
479
+ * 根据值类型创建属性值节点
480
+ */
481
+ parseJsExp(node?: PropertyValue): PropertyValue;
470
482
  /**
471
483
  * 根据值类型创建属性值节点
472
484
  */
package/dist/index.umd.js CHANGED
@@ -15,8 +15,15 @@
15
15
  TokenType[TokenType["InsertionExp"] = 128] = "InsertionExp";
16
16
  TokenType[TokenType["Semicolon"] = 256] = "Semicolon";
17
17
  TokenType[TokenType["StaticInsExp"] = 512] = "StaticInsExp";
18
+ TokenType[TokenType["String"] = 1024] = "String";
19
+ TokenType[TokenType["Number"] = 2048] = "Number";
20
+ TokenType[TokenType["Boolean"] = 4096] = "Boolean";
21
+ TokenType[TokenType["Null"] = 8192] = "Null";
22
+ TokenType[TokenType["Undefined"] = 16384] = "Undefined";
18
23
  return TokenType;
19
24
  }({});
25
+ const BaseTokenType = TokenType.String | TokenType.Number | TokenType.Boolean | TokenType.Null | TokenType.Undefined;
26
+ const ValueTokenType = BaseTokenType | TokenType.InsertionExp | TokenType.StaticInsExp;
20
27
  let FakeType = function (FakeType) {
21
28
  FakeType[FakeType["If"] = 1] = "If";
22
29
  FakeType[FakeType["Fail"] = 2] = "Fail";
@@ -52,13 +59,15 @@
52
59
  ParseErrorCode[ParseErrorCode["INDENT_MISMATCH"] = 9005] = "INDENT_MISMATCH";
53
60
  ParseErrorCode[ParseErrorCode["MISSING_ASSIGN"] = 9006] = "MISSING_ASSIGN";
54
61
  ParseErrorCode[ParseErrorCode["INVALID_TAG_NAME"] = 9007] = "INVALID_TAG_NAME";
55
- ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9008] = "ELSE_WITHOUT_IF";
56
- ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9009] = "EMPTY_IF_BODY";
57
- ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9010] = "EMPTY_FOR_BODY";
58
- ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9011] = "MISSING_FOR_COLLECTION";
59
- ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9012] = "MISSING_FOR_SEMICOLON";
60
- ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9013] = "MISSING_FOR_ITEM";
61
- ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9014] = "PIPE_IN_WRONG_CONTEXT";
62
+ ParseErrorCode[ParseErrorCode["INVALID_PROP_KEY"] = 9008] = "INVALID_PROP_KEY";
63
+ ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9009] = "ELSE_WITHOUT_IF";
64
+ ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9010] = "EMPTY_IF_BODY";
65
+ ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9011] = "EMPTY_FOR_BODY";
66
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9012] = "MISSING_FOR_COLLECTION";
67
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9013] = "MISSING_FOR_SEMICOLON";
68
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9014] = "MISSING_FOR_ITEM";
69
+ ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9015] = "MISSING_PROP_ASSIGNMENT";
70
+ ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9016] = "PIPE_IN_WRONG_CONTEXT";
62
71
  return ParseErrorCode;
63
72
  }({});
64
73
  class ParseSyntaxError extends SyntaxError {
@@ -590,8 +599,30 @@
590
599
  this.setToken(TokenType.Dedent, '');
591
600
  return;
592
601
  }
593
- let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
594
- this.setToken(TokenType.Identifier, realValue);
602
+ let realValue, tokenType;
603
+ switch (value) {
604
+ case 'null':
605
+ realValue = null;
606
+ tokenType = TokenType.Null;
607
+ break;
608
+ case 'undefined':
609
+ realValue = undefined;
610
+ tokenType = TokenType.Undefined;
611
+ break;
612
+ case 'false':
613
+ realValue = false;
614
+ tokenType = TokenType.Boolean;
615
+ break;
616
+ case 'true':
617
+ realValue = true;
618
+ tokenType = TokenType.Boolean;
619
+ break;
620
+ default:
621
+ realValue = value;
622
+ tokenType = TokenType.Identifier;
623
+ break;
624
+ }
625
+ this.setToken(tokenType, realValue);
595
626
  }
596
627
  str(char) {
597
628
  const startOffset = this.preI,
@@ -617,7 +648,7 @@
617
648
  }
618
649
  value += nextC;
619
650
  }
620
- this.setToken(TokenType.Identifier, value);
651
+ this.setToken(TokenType.String, value);
621
652
  }
622
653
  number(char) {
623
654
  let value = char;
@@ -630,7 +661,7 @@
630
661
  value += nextC;
631
662
  this.next();
632
663
  }
633
- this.setToken(TokenType.Identifier, Number(value));
664
+ this.setToken(TokenType.Number, Number(value));
634
665
  }
635
666
  eof() {
636
667
  this.setToken(TokenType.Eof, 'End Of File');
@@ -909,7 +940,7 @@
909
940
  let _initProto;
910
941
  class Compiler {
911
942
  static {
912
- 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, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
943
+ 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);
913
944
  _initProto = _applyDecs$e[0];
914
945
  }
915
946
  errors = (_initProto(this), []);
@@ -917,7 +948,10 @@
917
948
  this.tokenizer = tokenizer;
918
949
  this.hooks = hooks;
919
950
  }
920
- addError(code, message, loc) {
951
+ addError(code, message, loc, node) {
952
+ if (node) {
953
+ node.hasError = true;
954
+ }
921
955
  this.errors.push({
922
956
  code,
923
957
  message,
@@ -1020,7 +1054,7 @@
1020
1054
  parseElementNode(node) {
1021
1055
  const tagToken = this.tokenizer.token;
1022
1056
  if (!(tagToken.type & TokenType.Identifier)) {
1023
- this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc());
1057
+ this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc(), node);
1024
1058
  while (!(this.tokenizer.token.type & TokenType.NewLine) && !this.tokenizer.isEof()) {
1025
1059
  this.tokenizer.nextToken();
1026
1060
  }
@@ -1040,7 +1074,7 @@
1040
1074
  parseConditionalNode(node) {
1041
1075
  const keyword = this.tokenizer.token.value;
1042
1076
  this.tokenizer.condExp();
1043
- const condition = this.parsePropertyValue();
1077
+ const condition = this.parseJsExp();
1044
1078
  this.tokenizer.nextToken();
1045
1079
  this.tokenizer.nextToken();
1046
1080
  node.type = keyword === 'if' ? NodeType.If : keyword === 'else' ? NodeType.Else : NodeType.Fail;
@@ -1053,22 +1087,22 @@
1053
1087
  parseLoopNode(node) {
1054
1088
  const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
1055
1089
  this.tokenizer.nextToken();
1056
- const collection = this.parsePropertyValue();
1090
+ const collection = this.parseJsExp();
1057
1091
  if (!collection.value && collection.value !== 0) {
1058
- this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc);
1092
+ this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc, node);
1059
1093
  }
1060
1094
  const semicolonToken = this.tokenizer.nextToken();
1061
1095
  if (!(semicolonToken.type & TokenType.Semicolon)) {
1062
- this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc());
1096
+ this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc(), node);
1063
1097
  }
1064
1098
  const itemToken = this.tokenizer.nextToken();
1065
1099
  const isDestruct = itemToken.type === TokenType.InsertionExp;
1066
1100
  if (isDestruct) {
1067
1101
  itemToken.value = '{' + itemToken.value + '}';
1068
1102
  }
1069
- const item = this.parsePropertyValue();
1103
+ const item = this.parseJsExp();
1070
1104
  if (!item.value && item.value !== 0) {
1071
- this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc());
1105
+ this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc(), node);
1072
1106
  }
1073
1107
  let char = this.tokenizer.peekChar(),
1074
1108
  key,
@@ -1077,16 +1111,16 @@
1077
1111
  this.tokenizer.nextToken();
1078
1112
  if (this.tokenizer.peekChar() !== '\n') {
1079
1113
  this.tokenizer.jsExp();
1080
- key = this.parsePropertyValue();
1114
+ key = this.parseJsExp();
1081
1115
  }
1082
1116
  } else if (char === '\n') ; else {
1083
1117
  this.tokenizer.nextToken();
1084
- index = this.parsePropertyValue();
1118
+ index = this.parseJsExp();
1085
1119
  if (this.tokenizer.peekChar() === ';') {
1086
1120
  this.tokenizer.nextToken();
1087
1121
  if (this.tokenizer.peekChar() !== '\n') {
1088
1122
  this.tokenizer.jsExp();
1089
- key = this.parsePropertyValue();
1123
+ key = this.parseJsExp();
1090
1124
  }
1091
1125
  }
1092
1126
  }
@@ -1120,23 +1154,41 @@
1120
1154
  attributeList() {
1121
1155
  const props = [];
1122
1156
  while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
1123
- props.push(this.parseProperty());
1157
+ const prop = this.parseProperty();
1158
+ if (prop) {
1159
+ props.push(prop);
1160
+ }
1124
1161
  }
1125
1162
  return props;
1126
1163
  }
1127
1164
  parseProperty(node) {
1128
1165
  node.type = NodeType.Property;
1129
- node.key = this.parsePropertyKey();
1130
- const token = this.tokenizer.nextToken();
1131
- if (token.value === '=') {
1132
- this.tokenizer.nextToken();
1133
- node.value = this.parsePropertyValue();
1166
+ if (this.tokenizer.token.type !== TokenType.Identifier) {
1167
+ this.addError(ParseErrorCode.INVALID_PROP_KEY, `属性名 "${this.tokenizer.token.value}" 不合法`, this.tokenizer.token.loc ?? this.tokenizer.emptyLoc(), node);
1134
1168
  this.tokenizer.nextToken();
1135
- } else {
1136
- this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc());
1169
+ return null;
1137
1170
  }
1171
+ node.key = this.parsePropertyKey();
1172
+ const token = this.tokenizer.nextToken();
1173
+ if (token.value !== '=') {
1174
+ this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
1175
+ node.loc.start = node.key.loc.start;
1176
+ node.loc.end = node.key.loc.end;
1177
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1178
+ return node;
1179
+ }
1180
+ const valueToken = this.tokenizer.nextToken();
1181
+ if ((valueToken.type & ValueTokenType) === 0) {
1182
+ this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
1183
+ node.loc.start = node.key.loc.start;
1184
+ node.loc.end = node.key.loc.end;
1185
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1186
+ return node;
1187
+ }
1188
+ node.value = this.parsePropertyValue();
1189
+ this.tokenizer.nextToken();
1138
1190
  node.loc.start = node.key.loc.start;
1139
- node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
1191
+ node.loc.end = node.value.loc.end;
1140
1192
  node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1141
1193
  return node;
1142
1194
  }
@@ -1145,7 +1197,7 @@
1145
1197
  node.key = this.tokenizer.token.value;
1146
1198
  return node;
1147
1199
  }
1148
- parsePropertyValue(node) {
1200
+ parseJsExp(node) {
1149
1201
  const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1150
1202
  _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
1151
1203
  hookType = _this$tokenizer$_hook4[0],
@@ -1154,7 +1206,7 @@
1154
1206
  node.value = value;
1155
1207
  return node;
1156
1208
  }
1157
- parseName(node) {
1209
+ parsePropertyValue(node) {
1158
1210
  const _this$tokenizer$_hook5 = this.tokenizer._hook({}),
1159
1211
  _this$tokenizer$_hook6 = _slicedToArray(_this$tokenizer$_hook5, 2),
1160
1212
  hookType = _this$tokenizer$_hook6[0],
@@ -1163,6 +1215,15 @@
1163
1215
  node.value = value;
1164
1216
  return node;
1165
1217
  }
1218
+ parseName(node) {
1219
+ const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
1220
+ _this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
1221
+ hookType = _this$tokenizer$_hook8[0],
1222
+ value = _this$tokenizer$_hook8[1];
1223
+ node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
1224
+ node.value = value;
1225
+ return node;
1226
+ }
1166
1227
  }
1167
1228
  function NodeLoc(target, context) {
1168
1229
  return function (_node) {