@litert/typeguard 1.0.0 → 1.2.0

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.
Files changed (74) hide show
  1. package/CHANGES.md +15 -0
  2. package/lib/BuiltInTypeCompiler.d.ts +4 -4
  3. package/lib/BuiltInTypeCompiler.d.ts.map +1 -1
  4. package/lib/BuiltInTypeCompiler.js +167 -166
  5. package/lib/BuiltInTypeCompiler.js.map +1 -1
  6. package/lib/BuiltInTypes.d.ts +1 -1
  7. package/lib/BuiltInTypes.js +37 -36
  8. package/lib/BuiltInTypes.js.map +1 -1
  9. package/lib/Common.d.ts +13 -9
  10. package/lib/Common.d.ts.map +1 -1
  11. package/lib/Common.js +1 -1
  12. package/lib/Compiler.d.ts +2 -2
  13. package/lib/Compiler.d.ts.map +1 -1
  14. package/lib/Compiler.js +77 -72
  15. package/lib/Compiler.js.map +1 -1
  16. package/lib/Context.d.ts +2 -2
  17. package/lib/Context.js +3 -2
  18. package/lib/Context.js.map +1 -1
  19. package/lib/FilterCompiler.d.ts +5 -5
  20. package/lib/FilterCompiler.d.ts.map +1 -1
  21. package/lib/FilterCompiler.js +25 -24
  22. package/lib/FilterCompiler.js.map +1 -1
  23. package/lib/InlineCompiler.d.ts +12 -5
  24. package/lib/InlineCompiler.d.ts.map +1 -1
  25. package/lib/InlineCompiler.js +14 -5
  26. package/lib/InlineCompiler.js.map +1 -1
  27. package/lib/Internal.d.ts +2 -1
  28. package/lib/Internal.d.ts.map +1 -1
  29. package/lib/Internal.js +12 -10
  30. package/lib/Internal.js.map +1 -1
  31. package/lib/Modifiers.d.ts +1 -1
  32. package/lib/Modifiers.js +2 -1
  33. package/lib/Modifiers.js.map +1 -1
  34. package/lib/index.d.ts +5 -5
  35. package/lib/index.js +19 -7
  36. package/lib/index.js.map +1 -1
  37. package/lib/langs/JavaScript.d.ts +2 -2
  38. package/lib/langs/JavaScript.d.ts.map +1 -1
  39. package/lib/langs/JavaScript.js +30 -23
  40. package/lib/langs/JavaScript.js.map +1 -1
  41. package/package.json +18 -13
  42. package/src/{samples → examples}/quick-start.ts +22 -12
  43. package/src/lib/BuiltInTypeCompiler.ts +171 -171
  44. package/src/lib/BuiltInTypes.ts +36 -36
  45. package/src/lib/Common.ts +15 -10
  46. package/src/lib/Compiler.ts +213 -208
  47. package/src/lib/Context.ts +3 -3
  48. package/src/lib/FilterCompiler.ts +84 -84
  49. package/src/lib/InlineCompiler.ts +35 -14
  50. package/src/lib/Internal.ts +12 -10
  51. package/src/lib/Modifiers.ts +2 -2
  52. package/src/lib/index.ts +5 -5
  53. package/src/lib/langs/JavaScript.ts +34 -24
  54. package/src/test/00-all.ts +11 -9
  55. package/src/test/01-elemental-types.ts +1111 -1110
  56. package/src/test/02-array-and-list.ts +75 -75
  57. package/src/test/03-tuple.ts +87 -87
  58. package/src/test/04-from-string.ts +849 -848
  59. package/src/test/05-string-asserts.ts +422 -422
  60. package/src/test/06-structure.ts +107 -107
  61. package/src/test/07-modifiers.ts +151 -42
  62. package/src/test/08-map-and-dict.ts +46 -46
  63. package/src/test/09-exceptions.ts +67 -0
  64. package/src/test/abstracts.ts +52 -43
  65. package/dist/typeguard.amd.d.ts +0 -588
  66. package/dist/typeguard.amd.d.ts.map +0 -1
  67. package/dist/typeguard.amd.js +0 -2063
  68. package/dist/typeguard.amd.js.map +0 -1
  69. package/dist/typeguard.system.d.ts +0 -588
  70. package/dist/typeguard.system.d.ts.map +0 -1
  71. package/dist/typeguard.system.js +0 -2179
  72. package/dist/typeguard.system.js.map +0 -1
  73. package/tsconfig-amd.json +0 -72
  74. package/tsconfig-systemjs.json +0 -72
@@ -1,2063 +0,0 @@
1
- /*
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * https://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- define("Common", ["require", "exports"], function (require, exports) {
17
- "use strict";
18
- Object.defineProperty(exports, "__esModule", { value: true });
19
- });
20
- /**
21
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
22
- *
23
- * Licensed under the Apache License, Version 2.0 (the "License");
24
- * you may not use this file except in compliance with the License.
25
- * You may obtain a copy of the License at
26
- *
27
- * https://www.apache.org/licenses/LICENSE-2.0
28
- *
29
- * Unless required by applicable law or agreed to in writing, software
30
- * distributed under the License is distributed on an "AS IS" BASIS,
31
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32
- * See the License for the specific language governing permissions and
33
- * limitations under the License.
34
- */
35
- define("Internal", ["require", "exports"], function (require, exports) {
36
- "use strict";
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.MAP_SUFFIX = "{}";
39
- exports.LIST_SUFFIX = "[]";
40
- exports.MODIFIER_PREFIX = "$.";
41
- exports.FILTER_PREFIX = "|";
42
- exports.IMPLICIT_SYMBOL = "?";
43
- exports.PREDEF_TYPE_SYMBOL = "@";
44
- exports.NEGATIVE_SYMBOL = "!";
45
- exports.KEY_MAP_SUFFIX = `->${exports.MAP_SUFFIX}`;
46
- exports.KEY_LIST_SUFFIX = `->${exports.LIST_SUFFIX}`;
47
- exports.KEY_ARRAY_SUFFIX = /->\[\s*(\d+)(\s*,\s*(\d+)?)?\s*\]$/;
48
- exports.KEY_STRICT_SUFFIX = "->()";
49
- exports.KEY_EQUAL_SUFFIX = "->(=)";
50
- var EFlags;
51
- (function (EFlags) {
52
- EFlags[EFlags["FROM_STRING"] = 0] = "FROM_STRING";
53
- EFlags[EFlags["STRICT"] = 1] = "STRICT";
54
- EFlags[EFlags["OPTIONAL"] = 2] = "OPTIONAL";
55
- EFlags[EFlags["REQUIRED"] = 3] = "REQUIRED";
56
- EFlags[EFlags["ARRAY"] = 4] = "ARRAY";
57
- })(EFlags = exports.EFlags || (exports.EFlags = {}));
58
- var EFlagValue;
59
- (function (EFlagValue) {
60
- /**
61
- * Disabled.
62
- */
63
- EFlagValue[EFlagValue["NO"] = 0] = "NO";
64
- /**
65
- * Enabled but not inheritable.
66
- */
67
- EFlagValue[EFlagValue["YES"] = 1] = "YES";
68
- /**
69
- * Enabled and inheritable if not deep into sub element.
70
- */
71
- EFlagValue[EFlagValue["INHERIT"] = 2] = "INHERIT";
72
- /**
73
- * Enabled and inheritable even deep into sub element.
74
- */
75
- EFlagValue[EFlagValue["ELEMENT_INHERIT"] = 3] = "ELEMENT_INHERIT";
76
- })(EFlagValue = exports.EFlagValue || (exports.EFlagValue = {}));
77
- });
78
- /**
79
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
80
- *
81
- * Licensed under the Apache License, Version 2.0 (the "License");
82
- * you may not use this file except in compliance with the License.
83
- * You may obtain a copy of the License at
84
- *
85
- * https://www.apache.org/licenses/LICENSE-2.0
86
- *
87
- * Unless required by applicable law or agreed to in writing, software
88
- * distributed under the License is distributed on an "AS IS" BASIS,
89
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
90
- * See the License for the specific language governing permissions and
91
- * limitations under the License.
92
- */
93
- define("BuiltInTypes", ["require", "exports"], function (require, exports) {
94
- "use strict";
95
- Object.defineProperty(exports, "__esModule", { value: true });
96
- exports.STRING = "string";
97
- exports.ASCII_STRING = "ascii_string";
98
- exports.HEX_STRING = "hex_string";
99
- exports.LATIN_STRING = "latin_string";
100
- exports.NUMERIC = "numeric";
101
- exports.SAFE_INT = "safe_int";
102
- exports.INT = "int";
103
- exports.INT8 = "int8";
104
- exports.INT16 = "int16";
105
- exports.INT32 = "int32";
106
- exports.INT64 = "int64";
107
- exports.SAFE_UINT = "safe_uint";
108
- exports.UINT = "uint";
109
- exports.UINT8 = "uint8";
110
- exports.UINT16 = "uint16";
111
- exports.UINT32 = "uint32";
112
- exports.UINT64 = "uint64";
113
- exports.BOOLEAN = "boolean";
114
- exports.ARRAY = "array";
115
- exports.ANY = "any";
116
- exports.STRUCT = "struct";
117
- exports.NULL = "null";
118
- exports.UNDEFINED = "undefined";
119
- exports.VOID = "void";
120
- exports.FALSE = "false";
121
- exports.TRUE = "true";
122
- exports.FALSE_VALUE = "false_value";
123
- exports.TRUE_VALUE = "true_value";
124
- exports.OPTIONAL = "optional";
125
- exports.REQUIRED = "required";
126
- exports.DECIMAL = "decimal";
127
- exports.NUMBER = "number";
128
- exports.FLOAT = "float";
129
- exports.UDECIMAL = "udecimal";
130
- exports.UFLOAT = "ufloat";
131
- });
132
- /**
133
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
134
- *
135
- * Licensed under the Apache License, Version 2.0 (the "License");
136
- * you may not use this file except in compliance with the License.
137
- * You may obtain a copy of the License at
138
- *
139
- * https://www.apache.org/licenses/LICENSE-2.0
140
- *
141
- * Unless required by applicable law or agreed to in writing, software
142
- * distributed under the License is distributed on an "AS IS" BASIS,
143
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144
- * See the License for the specific language governing permissions and
145
- * limitations under the License.
146
- */
147
- define("BuiltInTypeCompiler", ["require", "exports", "Internal", "BuiltInTypes"], function (require, exports, I, B) {
148
- "use strict";
149
- Object.defineProperty(exports, "__esModule", { value: true });
150
- const BUILT_IN_TYPES = {
151
- [B.STRING]: {
152
- "kind": "string",
153
- "string": true,
154
- "constructed": false,
155
- "elemental": true
156
- },
157
- [B.ASCII_STRING]: {
158
- "kind": "string",
159
- "string": true,
160
- "constructed": false,
161
- "elemental": true
162
- },
163
- [B.HEX_STRING]: {
164
- "kind": "string",
165
- "string": true,
166
- "constructed": false,
167
- "elemental": true
168
- },
169
- [B.LATIN_STRING]: {
170
- "kind": "string",
171
- "string": true,
172
- "constructed": false,
173
- "elemental": true
174
- },
175
- [B.NUMERIC]: {
176
- "kind": "number",
177
- "string": true,
178
- "constructed": false,
179
- "elemental": true
180
- },
181
- [B.SAFE_INT]: {
182
- "kind": "number",
183
- "string": false,
184
- "constructed": false,
185
- "elemental": true
186
- },
187
- [B.INT]: {
188
- "kind": "number",
189
- "string": false,
190
- "constructed": false,
191
- "elemental": true
192
- },
193
- [B.INT8]: {
194
- "kind": "number",
195
- "string": false,
196
- "constructed": false,
197
- "elemental": true
198
- },
199
- [B.INT16]: {
200
- "kind": "number",
201
- "string": false,
202
- "constructed": false,
203
- "elemental": true
204
- },
205
- [B.INT32]: {
206
- "kind": "number",
207
- "string": false,
208
- "constructed": false,
209
- "elemental": true
210
- },
211
- [B.INT64]: {
212
- "kind": "number",
213
- "string": false,
214
- "constructed": false,
215
- "elemental": true
216
- },
217
- [B.SAFE_UINT]: {
218
- "kind": "number",
219
- "string": false,
220
- "constructed": false,
221
- "elemental": true
222
- },
223
- [B.UINT]: {
224
- "kind": "number",
225
- "string": false,
226
- "constructed": false,
227
- "elemental": true
228
- },
229
- [B.UINT8]: {
230
- "kind": "number",
231
- "string": false,
232
- "constructed": false,
233
- "elemental": true
234
- },
235
- [B.UINT16]: {
236
- "kind": "number",
237
- "string": false,
238
- "constructed": false,
239
- "elemental": true
240
- },
241
- [B.UINT32]: {
242
- "kind": "number",
243
- "string": false,
244
- "constructed": false,
245
- "elemental": true
246
- },
247
- [B.UINT64]: {
248
- "kind": "number",
249
- "string": false,
250
- "constructed": false,
251
- "elemental": true
252
- },
253
- [B.BOOLEAN]: {
254
- "kind": "boolean",
255
- "string": false,
256
- "constructed": false,
257
- "elemental": true
258
- },
259
- [B.ARRAY]: {
260
- "kind": "array",
261
- "string": false,
262
- "constructed": true,
263
- "elemental": false
264
- },
265
- [B.ANY]: {
266
- "kind": "unknown",
267
- "string": false,
268
- "constructed": false,
269
- "elemental": false
270
- },
271
- [B.STRUCT]: {
272
- "kind": "struct",
273
- "string": false,
274
- "constructed": true,
275
- "elemental": false
276
- },
277
- [B.NULL]: {
278
- "kind": "null",
279
- "string": false,
280
- "constructed": false,
281
- "elemental": false
282
- },
283
- [B.UNDEFINED]: {
284
- "kind": "void",
285
- "string": false,
286
- "constructed": false,
287
- "elemental": false
288
- },
289
- [B.VOID]: {
290
- "kind": "void",
291
- "string": false,
292
- "constructed": false,
293
- "elemental": false
294
- },
295
- [B.FALSE]: {
296
- "kind": "boolean",
297
- "string": false,
298
- "constructed": false,
299
- "elemental": true
300
- },
301
- [B.TRUE]: {
302
- "kind": "boolean",
303
- "string": false,
304
- "constructed": false,
305
- "elemental": true
306
- },
307
- [B.FALSE_VALUE]: {
308
- "kind": "unknown",
309
- "string": false,
310
- "constructed": false,
311
- "elemental": false
312
- },
313
- [B.TRUE_VALUE]: {
314
- "kind": "unknown",
315
- "string": false,
316
- "constructed": false,
317
- "elemental": false
318
- },
319
- [B.OPTIONAL]: {
320
- "kind": "void",
321
- "string": false,
322
- "constructed": false,
323
- "elemental": false
324
- },
325
- [B.REQUIRED]: {
326
- "kind": "unknown",
327
- "string": false,
328
- "constructed": false,
329
- "elemental": false
330
- },
331
- [B.DECIMAL]: {
332
- "kind": "number",
333
- "string": true,
334
- "constructed": false,
335
- "elemental": true
336
- },
337
- [B.NUMBER]: {
338
- "kind": "number",
339
- "string": false,
340
- "constructed": false,
341
- "elemental": true
342
- },
343
- [B.FLOAT]: {
344
- "kind": "number",
345
- "string": false,
346
- "constructed": false,
347
- "elemental": true
348
- },
349
- [B.UDECIMAL]: {
350
- "kind": "number",
351
- "string": true,
352
- "constructed": false,
353
- "elemental": true
354
- },
355
- [B.UFLOAT]: {
356
- "kind": "number",
357
- "string": false,
358
- "constructed": false,
359
- "elemental": true
360
- }
361
- };
362
- class BuiltInTypeCompiler {
363
- constructor(_lang) {
364
- this._lang = _lang;
365
- }
366
- isStringType(type) {
367
- return this.isBuiltInType(type) && BUILT_IN_TYPES[type].string;
368
- }
369
- isConstructed(type) {
370
- return this.isBuiltInType(type) && BUILT_IN_TYPES[type].constructed;
371
- }
372
- isElemental(type) {
373
- return this.isBuiltInType(type) && BUILT_IN_TYPES[type].elemental;
374
- }
375
- isBuiltInType(type) {
376
- return BUILT_IN_TYPES[type] !== undefined;
377
- }
378
- compile(type, ctx, args) {
379
- const fromString = !!(ctx.flags[I.EFlags.FROM_STRING] &&
380
- this.isBuiltInType(type) && (BUILT_IN_TYPES[type].kind === "number" ||
381
- BUILT_IN_TYPES[type].kind === "boolean" ||
382
- BUILT_IN_TYPES[type].kind === "null"));
383
- switch (type) {
384
- case B.NULL: {
385
- if (fromString) {
386
- return this._lang.or([
387
- this._lang.isNull(ctx.vName, true),
388
- this._lang.eq(ctx.vName, this._lang.literal("null"))
389
- ]);
390
- }
391
- return this._lang.isNull(ctx.vName, true);
392
- }
393
- case B.ANY: {
394
- return this._lang.literal(true);
395
- }
396
- case B.ARRAY: {
397
- return this._isArray(ctx, args);
398
- }
399
- case B.STRING: {
400
- return this._isString(ctx, args);
401
- }
402
- case B.ASCII_STRING: {
403
- return this._isString(ctx, args, "[\\u0000-\\u007F]");
404
- }
405
- case B.LATIN_STRING: {
406
- return this._isString(ctx, args, "[\\u0000-\\u024F\\u2C60-\\u2C7F]");
407
- }
408
- case B.HEX_STRING: {
409
- return this._isString(ctx, args, "[0-9A-Fa-f]");
410
- }
411
- case B.UFLOAT: {
412
- return this._isNumber(ctx, [0, NaN], fromString);
413
- }
414
- case B.FLOAT:
415
- case B.NUMBER: {
416
- return this._isNumber(ctx, args, fromString);
417
- }
418
- case B.INT: {
419
- return this._isInteger(ctx, args, fromString);
420
- }
421
- case B.INT64: {
422
- return this._isInteger(ctx, [], fromString);
423
- }
424
- case B.INT8: {
425
- return this._isInteger(ctx, [-0x80, 0x7F], fromString);
426
- }
427
- case B.INT16: {
428
- return this._isInteger(ctx, [-0x8000, 0x7FFF], fromString);
429
- }
430
- case B.INT32: {
431
- return this._isInteger(ctx, [-0x80000000, 0x7FFFFFFF], fromString);
432
- }
433
- case B.SAFE_INT: {
434
- return this._isInteger(ctx, [this._lang.minSafeInteger, this._lang.maxSafeInteger], fromString);
435
- }
436
- case B.UINT:
437
- case B.UINT64: {
438
- return this._isInteger(ctx, [0, NaN], fromString);
439
- }
440
- case B.UINT8: {
441
- return this._isInteger(ctx, [0, 0xFF], fromString);
442
- }
443
- case B.UINT16: {
444
- return this._isInteger(ctx, [0, 0xFFFF], fromString);
445
- }
446
- case B.UINT32: {
447
- return this._isInteger(ctx, [0, 0xFFFFFFFF], fromString);
448
- }
449
- case B.SAFE_UINT: {
450
- return this._isInteger(ctx, [0, this._lang.maxSafeInteger], fromString);
451
- }
452
- case B.BOOLEAN: {
453
- if (fromString) {
454
- return this._lang.or([
455
- this._lang.isBoolean(ctx.vName, true),
456
- this._lang.isBoolean(this._lang.str2Bool(ctx.vName), true)
457
- ]);
458
- }
459
- return this._lang.isBoolean(ctx.vName, true);
460
- }
461
- case B.TRUE: {
462
- if (fromString) {
463
- return this._lang.or([
464
- this._lang.eq(ctx.vName, this._lang.literal(true)),
465
- this._lang.eq(this._lang.str2Bool(ctx.vName), this._lang.literal(true))
466
- ]);
467
- }
468
- return this._lang.eq(ctx.vName, this._lang.literal(true));
469
- }
470
- case B.FALSE: {
471
- if (fromString) {
472
- return this._lang.or([
473
- this._lang.eq(ctx.vName, this._lang.literal(false)),
474
- this._lang.eq(this._lang.str2Bool(ctx.vName), this._lang.literal(false))
475
- ]);
476
- }
477
- return this._lang.eq(ctx.vName, this._lang.literal(false));
478
- }
479
- case B.TRUE_VALUE: {
480
- return this._lang.isTrueValue(ctx.vName);
481
- }
482
- case B.FALSE_VALUE: {
483
- return this._lang.isFalseValue(ctx.vName);
484
- }
485
- case B.VOID:
486
- case B.OPTIONAL:
487
- case B.UNDEFINED: {
488
- if (ctx.flags[I.EFlags.REQUIRED]) {
489
- throw new Error(`Conflicted: Can not use "optional" with "required" type.`);
490
- }
491
- if (ctx.flags[I.EFlags.OPTIONAL]) {
492
- return this._lang.literal(true);
493
- }
494
- ctx.flags[I.EFlags.OPTIONAL] = I.EFlagValue.YES;
495
- return this._lang.isUndefined(ctx.vName, true);
496
- }
497
- case B.REQUIRED: {
498
- if (ctx.flags[I.EFlags.OPTIONAL]) {
499
- throw new Error(`Conflicted: Can not use "required" with "optional" type.`);
500
- }
501
- if (ctx.flags[I.EFlags.REQUIRED]) {
502
- return this._lang.literal(true);
503
- }
504
- ctx.flags[I.EFlags.REQUIRED] = I.EFlagValue.YES;
505
- return this._lang.isUndefined(ctx.vName, false);
506
- }
507
- case B.STRUCT: {
508
- return this._lang.isStrucutre(ctx.vName, true);
509
- }
510
- case B.NUMERIC: {
511
- if (args.length) {
512
- return this._isNumber(ctx, args, true);
513
- }
514
- return this._lang.isNumeric(ctx.vName, true);
515
- }
516
- case B.DECIMAL: {
517
- return this._isDecimal(ctx, args);
518
- }
519
- case B.UDECIMAL: {
520
- return this._isDecimal(ctx, args, true);
521
- }
522
- }
523
- throw new TypeError(`Unknown type ${type}.`);
524
- }
525
- _isDecimal(ctx, params, unsigned = false) {
526
- if (params[0] <= 0) {
527
- throw new RangeError(`Arg 0 can not be zero for decimal.`);
528
- }
529
- const sign = unsigned ? "" : "[-+]?";
530
- switch (params.length) {
531
- default:
532
- case 0: {
533
- return this._lang.and([
534
- this._lang.isString(ctx.vName, true),
535
- this._lang.matchRegExp(ctx.vName, `^${sign}([1-9]\\d*|0)(\\.\\d+)?$`)
536
- ]);
537
- }
538
- case 1: {
539
- return this._lang.and([
540
- this._lang.isString(ctx.vName, true),
541
- this._lang.matchRegExp(ctx.vName, `^${sign}([1-9]\\d*|0)(\\.\\d+)?$`),
542
- this._lang.ifElseOp(this._lang.instr(ctx.vName, this._lang.literal(".")), this._lang.lte(this._lang.stringLength(ctx.vName), params[0] + 1), this._lang.lte(this._lang.stringLength(ctx.vName), params[0]))
543
- ]);
544
- }
545
- case 2: {
546
- if (params[0] < params[1]) {
547
- throw new RangeError(`Arg 0 should not be larger than arg 1 for decimal.`);
548
- }
549
- if (params[1] === 0) {
550
- return this._lang.and([
551
- this._lang.isString(ctx.vName, true),
552
- this._lang.matchRegExp(ctx.vName, `^${sign}([1-9]\\d{0,${params[0] - 1}}|0)$`)
553
- ]);
554
- }
555
- if (params[0] === params[1]) {
556
- return this._lang.and([
557
- this._lang.isString(ctx.vName, true),
558
- this._lang.matchRegExp(ctx.vName, `^${sign}0\\.\\d{${params[1]}}$`)
559
- ]);
560
- }
561
- return this._lang.matchRegExp(ctx.vName, `^${sign}([1-9]\\d{0,${params[0] - params[1] - 1}}|0)\\.\\d{${params[1]}}$`);
562
- }
563
- }
564
- }
565
- _isArray(ctx, params) {
566
- switch (params.length) {
567
- default:
568
- case 0: {
569
- return this._lang.isArray(ctx.vName, true);
570
- }
571
- case 1: {
572
- if (!Number.isInteger(params[0]) || params[0] < 0) {
573
- throw new Error(`Invalid argument "${params[0]}" for array.`);
574
- }
575
- return this._lang.and([
576
- this._lang.isArray(ctx.vName, true),
577
- this._lang.eq(this._lang.arrayLength(ctx.vName), params[0])
578
- ]);
579
- }
580
- case 2: {
581
- if (!Number.isInteger(params[0]) || params[0] < 0) {
582
- throw new Error(`Invalid argument "${params[0]}" for array.`);
583
- }
584
- const result = [
585
- this._lang.isArray(ctx.vName, true),
586
- this._lang.gte(this._lang.arrayLength(ctx.vName), params[0])
587
- ];
588
- if (this._checkValidUInteger(params[1], `Invalid argument "${params[1]}" for array.`)) {
589
- if (params[0] > params[1]) {
590
- throw new RangeError(`Arg 0 should not be larger than arg 1 for array.`);
591
- }
592
- result.push(this._lang.lte(this._lang.arrayLength(ctx.vName), params[1]));
593
- }
594
- return this._lang.and(result);
595
- }
596
- }
597
- }
598
- _isNumber(ctx, params, fromString) {
599
- const result = [
600
- this._lang.isNumber(ctx.vName, true)
601
- ];
602
- switch (params.length) {
603
- default:
604
- case 0: {
605
- if (fromString) {
606
- result.push(this._lang.and([
607
- this._lang.isString(ctx.vName, true),
608
- this._lang.matchRegExp(ctx.vName, "^[-+]?\\d+(\\.\\d+)?$")
609
- ]));
610
- }
611
- return this._lang.or(result);
612
- }
613
- case 2: {
614
- let vName = ctx.vName;
615
- if (fromString) {
616
- ctx.trap(true);
617
- vName = this._lang.varName(ctx.vCursor++);
618
- }
619
- if (this._checkValidNumber(params[0], `Invalid argument "${params[0]}".`)) {
620
- result.push(this._lang.gte(vName, params[0]));
621
- }
622
- if (this._checkValidNumber(params[1], `Invalid argument "${params[1]}".`)) {
623
- if (params[0] > params[1]) {
624
- throw new RangeError(`Arg 0 should not be larger than arg 1 for number.`);
625
- }
626
- result.push(this._lang.lte(vName, params[1]));
627
- }
628
- if (result.length === 1) {
629
- throw new SyntaxError(`Invalid syntax of integer.`);
630
- }
631
- if (fromString) {
632
- ctx.untrap();
633
- return this._lang.and([
634
- this._lang.or([
635
- result[0],
636
- this._lang.and([
637
- this._lang.isString(ctx.vName, true),
638
- this._lang.matchRegExp(ctx.vName, "^[-+]?\\d+(\\.\\d+)?$")
639
- ])
640
- ]),
641
- result.length === 3 ? this._lang.closure([vName], [this._lang.str2Float(ctx.vName)], this._lang.returnValue(this._lang.and(result.slice(1)))) : result[1].replace(vName, this._lang.str2Float(ctx.vName))
642
- ]);
643
- }
644
- return this._lang.and(result);
645
- }
646
- }
647
- }
648
- _checkValidNumber(v, msg) {
649
- if (Number.isNaN(v)) {
650
- return false;
651
- }
652
- if (Number.isFinite(v)) {
653
- return true;
654
- }
655
- throw new TypeError(msg);
656
- }
657
- _checkValidInteger(v, msg) {
658
- if (typeof v === "string") {
659
- v = parseFloat(v);
660
- }
661
- if (Number.isNaN(v)) {
662
- return false;
663
- }
664
- if (Number.isInteger(v)) {
665
- return true;
666
- }
667
- throw new TypeError(msg);
668
- }
669
- _checkValidUInteger(v, msg) {
670
- if (Number.isNaN(v)) {
671
- return false;
672
- }
673
- if (Number.isInteger(v) && v > -1) {
674
- return true;
675
- }
676
- throw new TypeError(msg);
677
- }
678
- _isInteger(ctx, params, fromString) {
679
- const result = [
680
- this._lang.isInteger(ctx.vName, true)
681
- ];
682
- switch (params.length) {
683
- default:
684
- case 0: {
685
- if (fromString) {
686
- result.push(this._lang.and([
687
- this._lang.isString(ctx.vName, true),
688
- this._lang.matchRegExp(ctx.vName, "^[-+]?\\d+$")
689
- ]));
690
- }
691
- return this._lang.or(result);
692
- }
693
- case 2: {
694
- let vName = ctx.vName;
695
- if (fromString) {
696
- ctx.trap(true);
697
- vName = this._lang.varName(ctx.vCursor++);
698
- }
699
- if (this._checkValidInteger(params[0], `Invalid argument "${params[0]}" for integer.`)) {
700
- result.push(this._lang.gte(vName, params[0]));
701
- }
702
- if (this._checkValidInteger(params[1], `Invalid argument "${params[1]}" for integer.`)) {
703
- if (params[0] > params[1]) {
704
- throw new RangeError(`Arg 0 should not be larger than arg 1 for number.`);
705
- }
706
- result.push(this._lang.lte(vName, params[1]));
707
- }
708
- if (result.length === 1) {
709
- throw new SyntaxError(`Invalid syntax of integer.`);
710
- }
711
- if (fromString) {
712
- ctx.untrap();
713
- return this._lang.and([
714
- this._lang.or([
715
- result[0],
716
- this._lang.and([
717
- this._lang.isString(ctx.vName, true),
718
- this._lang.matchRegExp(ctx.vName, "^[-+]?\\d+$")
719
- ])
720
- ]),
721
- result.length === 3 ? this._lang.closure([vName], [this._lang.str2Int(ctx.vName)], this._lang.returnValue(this._lang.and(result.slice(1)))) : result[1].replace(vName, this._lang.str2Int(ctx.vName))
722
- ]);
723
- }
724
- return this._lang.and(result);
725
- }
726
- }
727
- }
728
- _isString(ctx, params, elementRegExp) {
729
- switch (params.length) {
730
- default:
731
- case 0: {
732
- return elementRegExp ? this._lang.and([
733
- this._lang.isString(ctx.vName, true),
734
- this._lang.matchRegExp(ctx.vName, `^${elementRegExp}*$`)
735
- ]) : this._lang.isString(ctx.vName, true);
736
- }
737
- case 1: {
738
- if (!Number.isInteger(params[0]) || params[0] < 0) {
739
- throw new Error(`Invalid argument "${params[0]}" for string.`);
740
- }
741
- return this._lang.and([
742
- this._lang.isString(ctx.vName, true),
743
- elementRegExp ? this._lang.matchRegExp(ctx.vName, `^${elementRegExp}{${params[0]}}$`) : this._lang.eq(this._lang.stringLength(ctx.vName), params[0])
744
- ]);
745
- }
746
- case 2: {
747
- if (!Number.isInteger(params[0]) || params[0] < 0) {
748
- throw new Error(`Invalid argument "${params[0]}" for string.`);
749
- }
750
- const result = [
751
- this._lang.isString(ctx.vName, true)
752
- ];
753
- if (elementRegExp) {
754
- if (this._checkValidUInteger(params[1], `Invalid argument "${params[1]}" for string.`)) {
755
- if (params[0] > params[1]) {
756
- throw new RangeError(`Arg 0 should not be larger than arg 1 for string.`);
757
- }
758
- result.push(this._lang.matchRegExp(ctx.vName, `^${elementRegExp}{${params[0]},${params[1]}}$`));
759
- }
760
- else {
761
- result.push(this._lang.matchRegExp(ctx.vName, `^${elementRegExp}{${params[0]},}}$`));
762
- }
763
- }
764
- else {
765
- if (this._checkValidUInteger(params[1], `Invalid argument "${params[1]}" for string.`)) {
766
- if (params[0] > params[1]) {
767
- throw new RangeError(`Arg 0 should not be larger than arg 1 for string.`);
768
- }
769
- result.push(this._lang.gte(this._lang.stringLength(ctx.vName), params[0]), this._lang.lte(this._lang.stringLength(ctx.vName), params[1]));
770
- }
771
- else {
772
- result.push(this._lang.gte(this._lang.stringLength(ctx.vName), this._lang.literal(params[0])));
773
- }
774
- }
775
- return this._lang.and(result);
776
- }
777
- }
778
- }
779
- }
780
- exports.BuiltInTypeCompiler = BuiltInTypeCompiler;
781
- });
782
- /**
783
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
784
- *
785
- * Licensed under the Apache License, Version 2.0 (the "License");
786
- * you may not use this file except in compliance with the License.
787
- * You may obtain a copy of the License at
788
- *
789
- * https://www.apache.org/licenses/LICENSE-2.0
790
- *
791
- * Unless required by applicable law or agreed to in writing, software
792
- * distributed under the License is distributed on an "AS IS" BASIS,
793
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
794
- * See the License for the specific language governing permissions and
795
- * limitations under the License.
796
- */
797
- define("Modifiers", ["require", "exports", "Internal"], function (require, exports, I) {
798
- "use strict";
799
- Object.defineProperty(exports, "__esModule", { value: true });
800
- exports.PREFIX = I.MODIFIER_PREFIX;
801
- exports.NOT = `${I.MODIFIER_PREFIX}not`;
802
- exports.OR = `${I.MODIFIER_PREFIX}or`;
803
- exports.AND = `${I.MODIFIER_PREFIX}and`;
804
- exports.MAP = `${I.MODIFIER_PREFIX}map`;
805
- exports.LIST = `${I.MODIFIER_PREFIX}list`;
806
- exports.ARRAY = `${I.MODIFIER_PREFIX}array`;
807
- exports.DICT = `${I.MODIFIER_PREFIX}dict`;
808
- exports.STRICT = `${I.MODIFIER_PREFIX}strict`;
809
- exports.STRING = `${I.MODIFIER_PREFIX}string`;
810
- exports.TUPLE = `${I.MODIFIER_PREFIX}tuple`;
811
- exports.EQUAL = `${I.MODIFIER_PREFIX}equal`;
812
- exports.TAG = `${I.MODIFIER_PREFIX}tag`;
813
- exports.TYPE = `${I.MODIFIER_PREFIX}type`;
814
- });
815
- /**
816
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
817
- *
818
- * Licensed under the Apache License, Version 2.0 (the "License");
819
- * you may not use this file except in compliance with the License.
820
- * You may obtain a copy of the License at
821
- *
822
- * https://www.apache.org/licenses/LICENSE-2.0
823
- *
824
- * Unless required by applicable law or agreed to in writing, software
825
- * distributed under the License is distributed on an "AS IS" BASIS,
826
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
827
- * See the License for the specific language governing permissions and
828
- * limitations under the License.
829
- */
830
- define("Context", ["require", "exports", "Internal"], function (require, exports, i) {
831
- "use strict";
832
- Object.defineProperty(exports, "__esModule", { value: true });
833
- class Context {
834
- constructor(vName, typeSlotName, referredTypes) {
835
- this.vName = vName;
836
- this.typeSlotName = typeSlotName;
837
- this.referredTypes = referredTypes;
838
- this.stack = [];
839
- this.vCursor = 0;
840
- this.flags = {};
841
- this.tracePoint = 0;
842
- this.trace = false;
843
- }
844
- trap(subjChanged = false) {
845
- this.stack.push({
846
- vName: this.vName,
847
- flags: this.flags
848
- });
849
- const prevFlags = this.flags;
850
- this.flags = {};
851
- for (const key in prevFlags) {
852
- if (subjChanged) {
853
- if (prevFlags[key] === i.EFlagValue.ELEMENT_INHERIT) {
854
- this.flags[key] = prevFlags[key];
855
- }
856
- }
857
- else if (prevFlags[key] === i.EFlagValue.INHERIT ||
858
- prevFlags[key] === i.EFlagValue.ELEMENT_INHERIT) {
859
- this.flags[key] = prevFlags[key];
860
- }
861
- }
862
- }
863
- untrap() {
864
- const prev = this.stack.pop();
865
- if (!prev) {
866
- throw new Error("Failed to pop stack.");
867
- }
868
- this.vName = prev.vName;
869
- this.flags = prev.flags;
870
- }
871
- }
872
- exports.Context = Context;
873
- });
874
- /**
875
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
876
- *
877
- * Licensed under the Apache License, Version 2.0 (the "License");
878
- * you may not use this file except in compliance with the License.
879
- * You may obtain a copy of the License at
880
- *
881
- * https://www.apache.org/licenses/LICENSE-2.0
882
- *
883
- * Unless required by applicable law or agreed to in writing, software
884
- * distributed under the License is distributed on an "AS IS" BASIS,
885
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
886
- * See the License for the specific language governing permissions and
887
- * limitations under the License.
888
- */
889
- define("FilterCompiler", ["require", "exports"], function (require, exports) {
890
- "use strict";
891
- Object.defineProperty(exports, "__esModule", { value: true });
892
- class FilterCompiler {
893
- constructor(_lang, _bitc) {
894
- this._lang = _lang;
895
- this._bitc = _bitc;
896
- }
897
- compile(rule, ctx) {
898
- let vName = ctx.vName;
899
- const filter = rule.slice(1).split(" ");
900
- if (filter.slice(2).length !== filter.slice(2).filter((x) => /^\d+(\.\d+)?$/.test(x)).length) {
901
- throw new TypeError("Only number is allowed as filter arguments.");
902
- }
903
- let ret = [];
904
- switch (filter[0]) {
905
- case "array.length":
906
- ret.push(this._lang.isArray(vName, true));
907
- vName = this._lang.arrayLength(vName);
908
- break;
909
- case "string.length":
910
- ret.push(this._lang.isString(vName, true));
911
- vName = this._lang.stringLength(vName);
912
- break;
913
- case "value":
914
- ret.push(this._lang.isNumber(vName, true));
915
- break;
916
- default:
917
- ret.push(this._bitc.compile(filter[0], ctx, []));
918
- break;
919
- }
920
- switch (filter[1]) {
921
- case "between":
922
- if (filter.length !== 4) {
923
- throw new TypeError(`Filter ${filter[1]} require 2 arguments.`);
924
- }
925
- ret.push(this._lang.gte(vName, filter[2]));
926
- ret.push(this._lang.lte(vName, filter[3]));
927
- break;
928
- case "gt":
929
- case ">":
930
- if (filter.length !== 3) {
931
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
932
- }
933
- ret.push(this._lang.gt(vName, filter[2]));
934
- break;
935
- case "ge":
936
- case "gte":
937
- case ">=":
938
- if (filter.length !== 3) {
939
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
940
- }
941
- ret.push(this._lang.gte(vName, filter[2]));
942
- break;
943
- case "lt":
944
- case "<":
945
- if (filter.length !== 3) {
946
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
947
- }
948
- ret.push(this._lang.lt(vName, filter[2]));
949
- break;
950
- case "le":
951
- case "lte":
952
- case "<=":
953
- if (filter.length !== 3) {
954
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
955
- }
956
- ret.push(this._lang.lte(vName, filter[2]));
957
- break;
958
- case "eq":
959
- case "==":
960
- if (filter.length !== 3) {
961
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
962
- }
963
- ret.push(this._lang.eq(vName, filter[2]));
964
- break;
965
- case "ne":
966
- case "!=":
967
- if (filter.length !== 3) {
968
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
969
- }
970
- ret.push(this._lang.ne(vName, filter[2]));
971
- break;
972
- case "timesof":
973
- if (filter.length !== 3) {
974
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
975
- }
976
- ret.push(this._lang.eq(this._lang.modOf(vName, filter[2]), "0"));
977
- break;
978
- default:
979
- throw new TypeError(`Unknown filter type "${filter[1]}".`);
980
- }
981
- return this._lang.and(ret);
982
- }
983
- }
984
- exports.FilterCompiler = FilterCompiler;
985
- });
986
- /**
987
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
988
- *
989
- * Licensed under the Apache License, Version 2.0 (the "License");
990
- * you may not use this file except in compliance with the License.
991
- * You may obtain a copy of the License at
992
- *
993
- * https://www.apache.org/licenses/LICENSE-2.0
994
- *
995
- * Unless required by applicable law or agreed to in writing, software
996
- * distributed under the License is distributed on an "AS IS" BASIS,
997
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
998
- * See the License for the specific language governing permissions and
999
- * limitations under the License.
1000
- */
1001
- define("Compiler", ["require", "exports", "Internal", "Modifiers", "Context", "BuiltInTypes", "BuiltInTypeCompiler", "FilterCompiler"], function (require, exports, I, M, Context_1, B, BuiltInTypeCompiler_1, FilterCompiler_1) {
1002
- "use strict";
1003
- Object.defineProperty(exports, "__esModule", { value: true });
1004
- class Compiler {
1005
- constructor(_lang, _builtInTypes, _filters) {
1006
- this._lang = _lang;
1007
- this._builtInTypes = _builtInTypes;
1008
- this._filters = _filters;
1009
- this._defTypes = {};
1010
- }
1011
- getPredefinedType(name) {
1012
- if (this._defTypes[name]) {
1013
- return this._defTypes[name];
1014
- }
1015
- return null;
1016
- }
1017
- compile(options) {
1018
- const referredTypes = {};
1019
- const ctx = new Context_1.Context(this._lang.varName("entry"), this._lang.varName("types"), referredTypes);
1020
- if (options.name) {
1021
- this._compile(ctx, [M.TYPE, options.name, options.rule]);
1022
- return this._defTypes[options.name];
1023
- }
1024
- else {
1025
- const ret = {
1026
- source: "",
1027
- arguments: [{
1028
- "name": ctx.vName,
1029
- "type": "unknown"
1030
- }],
1031
- typeSlotName: ctx.typeSlotName,
1032
- referredTypes: []
1033
- };
1034
- ret.source = this._compile(ctx, options.rule);
1035
- ret.referredTypes = Object.keys(ctx.referredTypes);
1036
- return ret;
1037
- }
1038
- }
1039
- _compile(ctx, rules) {
1040
- switch (typeof rules) {
1041
- case "string":
1042
- return this._compileStringRule(ctx, rules);
1043
- case "boolean":
1044
- if (ctx.flags[I.EFlags.FROM_STRING]) {
1045
- return this._lang.or([
1046
- this._lang.eq(ctx.vName, this._lang.literal(rules)),
1047
- this._lang.eq(this._lang.str2Bool(ctx.vName), this._lang.literal(rules))
1048
- ]);
1049
- }
1050
- return this._lang.eq(ctx.vName, this._lang.literal(rules));
1051
- case "number":
1052
- if (ctx.flags[I.EFlags.FROM_STRING]) {
1053
- return this._lang.or([
1054
- this._lang.eq(ctx.vName, this._lang.literal(rules)),
1055
- this._lang.eq(this._lang.str2Float(ctx.vName), this._lang.literal(rules))
1056
- ]);
1057
- }
1058
- return this._lang.eq(ctx.vName, this._lang.literal(rules));
1059
- case "object":
1060
- if (Array.isArray(rules)) {
1061
- return this._compileModifiedRule(ctx, rules);
1062
- }
1063
- else if (rules === null) {
1064
- if (ctx.flags[I.EFlags.FROM_STRING]) {
1065
- return this._lang.or([
1066
- this._lang.isNull(ctx.vName, true),
1067
- this._lang.eq(ctx.vName, this._lang.literal("null"))
1068
- ]);
1069
- }
1070
- return this._lang.isNull(ctx.vName, true);
1071
- }
1072
- return this._compileStructuredRule(ctx, rules);
1073
- case "undefined":
1074
- return this._lang.isUndefined(ctx.vName, true);
1075
- }
1076
- throw new TypeError("Unknwn rules.");
1077
- }
1078
- _compileStringRule(ctx, rule) {
1079
- const strAssert = this._useStringAssert(ctx, rule);
1080
- if (strAssert !== false) {
1081
- return this._lang.and([
1082
- this._lang.isString(ctx.vName, true),
1083
- strAssert
1084
- ]);
1085
- }
1086
- if (rule[0] === I.IMPLICIT_SYMBOL) {
1087
- return this._lang.or([
1088
- this._builtInTypes.compile(B.VOID, ctx, []),
1089
- this._compileStringRule(ctx, rule.slice(1))
1090
- ]);
1091
- }
1092
- if (rule[0] === I.NEGATIVE_SYMBOL) {
1093
- return this._lang.not(this._compileStringRule(ctx, rule.slice(1)));
1094
- }
1095
- let regResult;
1096
- /**
1097
- * For rules like `xxx[123]` or `xxx[1,5]`.
1098
- */
1099
- if (regResult = rule.match(/\[\s*(\d*|\d+\s*,\s*\d*)\s*\]$/)) {
1100
- if (regResult[1]) {
1101
- let range = regResult[1].split(",").map((x) => parseInt(x.trim()));
1102
- if (range.length === 1) {
1103
- return this._compileModifiedRule(ctx, [
1104
- M.ARRAY,
1105
- range[0],
1106
- rule.substr(0, regResult.index)
1107
- ]);
1108
- }
1109
- else if (Number.isNaN(range[1])) {
1110
- return this._compileModifiedRule(ctx, [
1111
- M.ARRAY,
1112
- [range[0]],
1113
- rule.substr(0, regResult.index)
1114
- ]);
1115
- }
1116
- else {
1117
- return this._compileModifiedRule(ctx, [
1118
- M.ARRAY,
1119
- range,
1120
- rule.substr(0, regResult.index)
1121
- ]);
1122
- }
1123
- }
1124
- else {
1125
- return this._compileModifiedRule(ctx, [
1126
- M.LIST,
1127
- rule.substr(0, regResult.index)
1128
- ]);
1129
- }
1130
- }
1131
- /**
1132
- * For rules like `xxx{}`.
1133
- */
1134
- if (rule.endsWith(I.MAP_SUFFIX)) {
1135
- return this._lang.and([
1136
- this._compileModifiedRule(ctx, [
1137
- M.MAP,
1138
- rule.slice(0, -2)
1139
- ])
1140
- ]);
1141
- }
1142
- if (rule[0] === I.PREDEF_TYPE_SYMBOL) {
1143
- return this._usePredefinedType(ctx, rule.slice(1));
1144
- }
1145
- /**
1146
- * For built-in-type rules like:
1147
- *
1148
- * - `string(20)`
1149
- * - `string(20, 30)`
1150
- * - `string`
1151
- * - `int(12, 34)`
1152
- */
1153
- if (regResult = rule.match(/^(\w+)(\(\s*(-?\d+(\.\d+)?)?\s*,?\s*(-?\d+(\.\d+)?)?\s*\))?$/)) {
1154
- if (regResult[2]) {
1155
- const args = regResult[2].slice(1, -1).trim().split(",").map((x) => parseFloat(x.trim()));
1156
- return this._builtInTypes.compile(regResult[1], ctx, args);
1157
- }
1158
- return this._builtInTypes.compile(regResult[1], ctx, []);
1159
- }
1160
- if (rule[0] === I.FILTER_PREFIX) {
1161
- return this._filters.compile(rule, ctx);
1162
- }
1163
- throw new TypeError(`Unknown type "${rule}".`);
1164
- }
1165
- _usePredefinedType(ctx, typeName) {
1166
- this._validateTypeName(typeName);
1167
- ctx.referredTypes[typeName] = true;
1168
- return this._lang.call(this._lang.fieldIndex(ctx.typeSlotName, this._lang.literal(typeName)), ctx.vName);
1169
- }
1170
- _useStringAssert(ctx, rule) {
1171
- const assertRule = rule.match(/^:([-\w]+):/);
1172
- const offset = assertRule ? assertRule[1].length + 2 : 2;
1173
- switch ((assertRule && assertRule[1]) || rule.substr(0, 2)) {
1174
- case "==":
1175
- case "equal":
1176
- return this._lang.eq(ctx.vName, this._lang.literal(rule.slice(offset)));
1177
- case "%=":
1178
- case "equal-i":
1179
- return this._lang.eq(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase()));
1180
- case "!=":
1181
- case "not-equal":
1182
- return this._lang.ne(ctx.vName, this._lang.literal(rule.slice(offset)));
1183
- case "%!":
1184
- case "not-equal-i":
1185
- return this._lang.ne(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase()));
1186
- case "~=":
1187
- case "match":
1188
- return this._lang.matchRegExp(ctx.vName, rule.slice(offset));
1189
- case "~!":
1190
- case "not-match":
1191
- return this._lang.not(this._lang.matchRegExp(ctx.vName, rule.slice(offset)));
1192
- case "?=":
1193
- case "include":
1194
- return this._lang.instr(ctx.vName, this._lang.literal(rule.slice(offset)));
1195
- case "?!":
1196
- case "not-include":
1197
- return this._lang.not(this._lang.instr(ctx.vName, this._lang.literal(rule.slice(offset))));
1198
- case "*=":
1199
- case "include-i":
1200
- return this._lang.instr(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase()));
1201
- case "*!":
1202
- case "not-include-i":
1203
- return this._lang.not(this._lang.instr(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase())));
1204
- case "^=":
1205
- case "start-with":
1206
- return this._lang.startsWith(ctx.vName, this._lang.literal(rule.slice(offset)));
1207
- case "start-with-i":
1208
- return this._lang.startsWith(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase()));
1209
- case "^!":
1210
- case "not-start-with":
1211
- return this._lang.not(this._lang.startsWith(ctx.vName, this._lang.literal(rule.slice(offset))));
1212
- case "not-start-with-i":
1213
- return this._lang.not(this._lang.startsWith(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase())));
1214
- case "$=":
1215
- case "end-with":
1216
- return this._lang.endsWith(ctx.vName, this._lang.literal(rule.slice(offset)));
1217
- case "end-with-i":
1218
- return this._lang.endsWith(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase()));
1219
- case "$!":
1220
- case "not-end-with":
1221
- return this._lang.not(this._lang.endsWith(ctx.vName, this._lang.literal(rule.slice(offset))));
1222
- case "not-end-with-i":
1223
- return this._lang.not(this._lang.endsWith(this._lang.lowerCase(ctx.vName), this._lang.literal(rule.slice(offset).toLowerCase())));
1224
- default:
1225
- if (rule.startsWith("=")) {
1226
- return this._lang.eq(ctx.vName, this._lang.literal(rule.slice(1)));
1227
- }
1228
- if (rule.startsWith("~")) {
1229
- return this._lang.matchRegExp(ctx.vName, rule.slice(1));
1230
- }
1231
- }
1232
- return false;
1233
- }
1234
- _compileModifiedRule(ctx, rules) {
1235
- if (!rules.length) {
1236
- throw new TypeError(`Unknwon type "[]".`);
1237
- }
1238
- /**
1239
- * By default, use OR modifier.
1240
- */
1241
- if (typeof rules[0] !== "string" ||
1242
- !rules[0].startsWith(I.MODIFIER_PREFIX)) {
1243
- if (rules.length === 1) {
1244
- return this._compile(ctx, rules[0]);
1245
- }
1246
- rules.unshift(M.OR);
1247
- }
1248
- switch (rules[0]) {
1249
- case M.NOT: {
1250
- return this._lang.not(this._compileModifiedRule(ctx, rules.slice(1)));
1251
- }
1252
- case M.OR: {
1253
- return this._compileModifierOR(ctx, rules.slice(1));
1254
- }
1255
- case M.AND: {
1256
- return this._compileModifierAND(ctx, rules.slice(1));
1257
- }
1258
- case M.LIST: {
1259
- return this._compileModifierLIST(ctx, rules.slice(1));
1260
- }
1261
- case M.ARRAY: {
1262
- return this._compileModifierARRAY(ctx, rules.slice(1));
1263
- }
1264
- case M.DICT: {
1265
- return this._compileModifierDICT(ctx, rules.slice(1));
1266
- }
1267
- case M.MAP: {
1268
- return this._compileModifierMAP(ctx, rules.slice(1));
1269
- }
1270
- case M.TUPLE: {
1271
- return this._compileModifierTUPLE(ctx, rules.slice(1));
1272
- }
1273
- case M.EQUAL: {
1274
- return this._compileModifierEQUAL(ctx, rules.slice(1));
1275
- }
1276
- case M.STRICT: {
1277
- return this._compileModifierSTRICT(ctx, rules.slice(1));
1278
- }
1279
- case M.STRING: {
1280
- return this._compileModifierSTRING(ctx, rules.slice(1));
1281
- }
1282
- case M.TYPE: {
1283
- return this._compileModifierTYPE(ctx, rules.slice(1));
1284
- }
1285
- }
1286
- throw new TypeError(`Unknown modifier "${rules[0]}".`);
1287
- }
1288
- _compileModifierSTRING(ctx, rules) {
1289
- ctx.trap();
1290
- ctx.flags[I.EFlags.FROM_STRING] = I.EFlagValue.ELEMENT_INHERIT;
1291
- const result = this._compileModifiedRule(ctx, rules);
1292
- ctx.untrap();
1293
- return result;
1294
- }
1295
- _compileModifierOR(ctx, rules) {
1296
- let result = [];
1297
- for (const r of rules) {
1298
- ctx.trap();
1299
- result.push(this._compile(ctx, r));
1300
- ctx.untrap();
1301
- }
1302
- return this._lang.or(result);
1303
- }
1304
- _compileModifierAND(ctx, rules) {
1305
- return this._lang.and(rules.map((rule) => this._compile(ctx, rule)));
1306
- }
1307
- _compileModifierLIST(ctx, rules) {
1308
- const result = [];
1309
- if (!ctx.flags[I.EFlags.ARRAY]) {
1310
- result.push(this._lang.isArray(ctx.vName, true));
1311
- ctx.flags[I.EFlags.ARRAY] = I.EFlagValue.INHERIT;
1312
- }
1313
- ctx.trap(true);
1314
- const CLOSURE_ARG = ctx.vName;
1315
- const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
1316
- ctx.vName = this._lang.varName(ctx.vCursor++);
1317
- if (rules[0] !== B.ANY) {
1318
- result.push(this._lang.closure([CLOSURE_PARAM], [CLOSURE_ARG], this._lang.series([
1319
- this._lang.forEach(CLOSURE_PARAM, ctx.vName, this._lang.ifThen(this._lang.not(this._compile(ctx, rules)), this._lang.returnValue(this._lang.literal(false)))),
1320
- this._lang.returnValue(this._lang.literal(true))
1321
- ])));
1322
- }
1323
- ctx.untrap();
1324
- return this._lang.and(result);
1325
- }
1326
- _compileModifierARRAY(ctx, rules) {
1327
- let a = 0;
1328
- let b = -1;
1329
- if (Number.isInteger(rules[0]) && rules[0] >= 0) {
1330
- a = rules[0];
1331
- }
1332
- else if (Array.isArray(rules[0])) {
1333
- switch (rules[0].length) {
1334
- default:
1335
- case 0: {
1336
- throw new TypeError(`Invalid arguments "${JSON.stringify(rules[0])}" for array.`);
1337
- }
1338
- case 1: {
1339
- a = rules[0][0];
1340
- b = 0xFFFFFFFF;
1341
- if (!Number.isInteger(a) || a < 0) {
1342
- throw new TypeError(`Invalid arguments "${JSON.stringify(rules[0])}" for array.`);
1343
- }
1344
- break;
1345
- }
1346
- case 2: {
1347
- a = rules[0][0];
1348
- b = rules[0][1];
1349
- if ((!Number.isInteger(a) || a < 0) ||
1350
- (!Number.isInteger(b) || b < 0) ||
1351
- a > b) {
1352
- throw new TypeError(`Invalid arguments "${JSON.stringify(rules[0])}" for array.`);
1353
- }
1354
- if (a === b) {
1355
- b = -1;
1356
- }
1357
- }
1358
- }
1359
- }
1360
- else {
1361
- throw new TypeError(`Invalid arguments "${JSON.stringify(rules[0])}" for array.`);
1362
- }
1363
- const result = [];
1364
- if (!ctx.flags[I.EFlags.ARRAY]) {
1365
- result.push(this._lang.isArray(ctx.vName, true));
1366
- ctx.flags[I.EFlags.ARRAY] = I.EFlagValue.INHERIT;
1367
- }
1368
- ctx.trap(true);
1369
- const CLOSURE_ARG = ctx.vName;
1370
- const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
1371
- ctx.vName = this._lang.varName(ctx.vCursor++);
1372
- switch (b) {
1373
- case -1: {
1374
- result.push(this._lang.eq(this._lang.arrayLength(CLOSURE_ARG), a));
1375
- break;
1376
- }
1377
- case 0xFFFFFFFF: {
1378
- result.push(this._lang.gte(this._lang.arrayLength(CLOSURE_ARG), a));
1379
- break;
1380
- }
1381
- default: {
1382
- result.push(this._lang.gte(this._lang.arrayLength(CLOSURE_ARG), a), this._lang.lte(this._lang.arrayLength(CLOSURE_ARG), b));
1383
- break;
1384
- }
1385
- }
1386
- if (rules[1] !== B.ANY) {
1387
- result.push(this._lang.closure([CLOSURE_PARAM], [CLOSURE_ARG], this._lang.series([
1388
- this._lang.forEach(CLOSURE_PARAM, ctx.vName, this._lang.ifThen(this._lang.not(this._compile(ctx, rules.slice(1))), this._lang.returnValue(this._lang.literal(false)))),
1389
- this._lang.returnValue(this._lang.literal(true))
1390
- ])));
1391
- }
1392
- ctx.untrap();
1393
- return this._lang.and(result);
1394
- }
1395
- _compileModifierTUPLE(ctx, rules) {
1396
- const result = [];
1397
- if (!ctx.flags[I.EFlags.ARRAY]) {
1398
- result.push(this._lang.isArray(ctx.vName, true));
1399
- ctx.flags[I.EFlags.ARRAY] = I.EFlagValue.INHERIT;
1400
- }
1401
- let type;
1402
- let dots;
1403
- let i = 0;
1404
- const types = rules.slice();
1405
- let tupleLength = 0;
1406
- while (1) {
1407
- type = types.shift();
1408
- if (type === undefined) {
1409
- break;
1410
- }
1411
- if (typeof type === "string" && type.startsWith("...")) {
1412
- throw new TypeError(`Invalid syntax for tuple: ${JSON.stringify(rules)}`);
1413
- }
1414
- if (typeof types[0] === "string" && types[0].startsWith("...")) {
1415
- ctx.trap();
1416
- dots = types.shift();
1417
- if (dots === "...") {
1418
- /**
1419
- * No more elements because "..." means all rest elements.
1420
- */
1421
- if (types.length) {
1422
- throw new TypeError(`Invalid syntax for tuple: ${JSON.stringify(rules)}`);
1423
- }
1424
- ctx.vName = this._lang.arraySlice(ctx.vName, i);
1425
- if (type !== "any") {
1426
- result.push(this._compileModifierLIST(ctx, type));
1427
- }
1428
- tupleLength = -1;
1429
- }
1430
- else if (!/^\d+$/.test(dots.slice(3))) {
1431
- throw new TypeError(`Invalid syntax for tuple: ${dots}`);
1432
- }
1433
- else {
1434
- const length = parseInt(dots.slice(3));
1435
- if (length <= 3) {
1436
- const vName = ctx.vName;
1437
- for (let j = 0; j < length; j++) {
1438
- ctx.vName = this._lang.arrayIndex(vName, i++);
1439
- result.push(this._compile(ctx, type));
1440
- }
1441
- }
1442
- else {
1443
- ctx.vName = this._lang.arraySlice(ctx.vName, i, i + length);
1444
- result.push(this._compileModifierARRAY(ctx, [length, type]));
1445
- i += length;
1446
- }
1447
- tupleLength += length;
1448
- }
1449
- }
1450
- else {
1451
- ctx.trap(true);
1452
- ctx.vName = this._lang.arrayIndex(ctx.vName, i++);
1453
- result.push(this._compile(ctx, type));
1454
- tupleLength++;
1455
- }
1456
- ctx.untrap();
1457
- }
1458
- if (tupleLength >= 0) {
1459
- result.splice(1, -1, this._lang.eq(this._lang.arrayLength(ctx.vName), tupleLength));
1460
- }
1461
- return this._lang.and(result);
1462
- }
1463
- _validateTypeName(name) {
1464
- if (typeof name !== "string" || !/^\w+$/.test(name)) {
1465
- throw new TypeError(`Invalid name ${JSON.stringify(name)} for a pre-defined type.`);
1466
- }
1467
- }
1468
- _compileModifierTYPE(ctx, rules) {
1469
- this._validateTypeName(rules[0]);
1470
- if (this._defTypes[rules[0]]) {
1471
- throw new Error(`Dplicated name ${JSON.stringify(rules[0])} for a pre-defined type.`);
1472
- }
1473
- this._defTypes[rules[0]] = this.compile({
1474
- rule: rules.slice(1)
1475
- });
1476
- return this._usePredefinedType(ctx, rules[0]);
1477
- }
1478
- _compileModifierSTRICT(ctx, rules) {
1479
- ctx.trap();
1480
- if (rules.length === 1) {
1481
- rules = rules[0];
1482
- }
1483
- ctx.flags[I.EFlags.STRICT] = I.EFlagValue.INHERIT;
1484
- const ret = this._compile(ctx, rules);
1485
- ctx.untrap();
1486
- return ret;
1487
- }
1488
- _compileModifierEQUAL(ctx, rules) {
1489
- ctx.trap();
1490
- if (rules.length === 1) {
1491
- rules = rules[0];
1492
- }
1493
- ctx.flags[I.EFlags.STRICT] = I.EFlagValue.ELEMENT_INHERIT;
1494
- const ret = this._compile(ctx, rules);
1495
- ctx.untrap();
1496
- return ret;
1497
- }
1498
- _compileModifierMAP(ctx, rules) {
1499
- if (rules.length === 1) {
1500
- rules = rules[0];
1501
- }
1502
- ctx.trap(true);
1503
- const CLOSURE_ARG = ctx.vName;
1504
- const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
1505
- const FOR_IN_KEY = this._lang.varName(ctx.vCursor++);
1506
- ctx.vName = this._lang.varName(ctx.vCursor++);
1507
- const result = this._lang.and([
1508
- this._lang.isStrucutre(CLOSURE_ARG, true),
1509
- this._lang.closure([CLOSURE_PARAM], [CLOSURE_ARG], this._lang.series([
1510
- this._lang.forIn(CLOSURE_PARAM, FOR_IN_KEY, ctx.vName, this._lang.ifThen(this._lang.not(this._compile(ctx, rules)), this._lang.returnValue(this._lang.literal(false)))),
1511
- this._lang.returnValue(this._lang.literal(true))
1512
- ]))
1513
- ]);
1514
- ctx.untrap();
1515
- return result;
1516
- }
1517
- _compileModifierDICT(ctx, rules) {
1518
- if (rules.length < 2 || !Array.isArray(rules[0])) {
1519
- throw new SyntaxError(`Invalid dict ${JSON.stringify(rules)}.`);
1520
- }
1521
- let tmp = {};
1522
- const id = `${Date.now()}${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`;
1523
- this._compileModifierTYPE(ctx, [
1524
- this._lang.varName(id),
1525
- rules.slice(1)
1526
- ]);
1527
- const type = `${I.PREDEF_TYPE_SYMBOL}${this._lang.varName(id)}`;
1528
- for (let key of rules[0]) {
1529
- if (typeof key !== "string") {
1530
- throw new SyntaxError(`Invalid key ${JSON.stringify(key)} for dict.`);
1531
- }
1532
- tmp[key] = type;
1533
- }
1534
- return this._compileStructuredRule(ctx, tmp);
1535
- }
1536
- _compileSimpleStructure(ctx, rules) {
1537
- const strict = !!ctx.flags[I.EFlags.STRICT];
1538
- const result = [
1539
- this._lang.isStrucutre(ctx.vName, true)
1540
- ];
1541
- const keys = [];
1542
- for (let k in rules) {
1543
- let rule = rules[k];
1544
- let optional = false;
1545
- if (k.endsWith(I.IMPLICIT_SYMBOL)) {
1546
- optional = true;
1547
- k = k.slice(0, -1);
1548
- }
1549
- ctx.trap(true);
1550
- if (k.endsWith(I.KEY_LIST_SUFFIX)) {
1551
- k = k.slice(0, -I.KEY_LIST_SUFFIX.length);
1552
- rule = [M.LIST, rule];
1553
- }
1554
- else if (k.endsWith(I.KEY_MAP_SUFFIX)) {
1555
- k = k.slice(0, -I.KEY_MAP_SUFFIX.length);
1556
- rule = [M.MAP, rule];
1557
- }
1558
- else if (k.endsWith(I.KEY_STRICT_SUFFIX)) {
1559
- k = k.slice(0, -I.KEY_STRICT_SUFFIX.length);
1560
- rule = [M.STRICT, rule];
1561
- }
1562
- else if (k.endsWith(I.KEY_EQUAL_SUFFIX)) {
1563
- k = k.slice(0, -I.KEY_STRICT_SUFFIX.length);
1564
- rule = [M.EQUAL, rule];
1565
- }
1566
- else {
1567
- const matchResult = k.match(I.KEY_ARRAY_SUFFIX);
1568
- if (matchResult) {
1569
- k = k.slice(0, matchResult.index);
1570
- if (matchResult[3]) {
1571
- rule = [
1572
- M.ARRAY,
1573
- [
1574
- parseInt(matchResult[1]),
1575
- parseInt(matchResult[3])
1576
- ],
1577
- rule
1578
- ];
1579
- }
1580
- else if (matchResult[2]) {
1581
- rule = [M.ARRAY, [parseInt(matchResult[1])], rule];
1582
- }
1583
- else {
1584
- rule = [M.ARRAY, parseInt(matchResult[1]), rule];
1585
- }
1586
- }
1587
- }
1588
- if (optional) {
1589
- if (this._isOrRule(rule)) {
1590
- rule.push(B.VOID);
1591
- }
1592
- else {
1593
- rule = [B.VOID, rule];
1594
- }
1595
- }
1596
- keys.push(k);
1597
- ctx.vName = this._lang.fieldIndex(ctx.vName, this._lang.literal(k));
1598
- result.push(this._compile(ctx, rule));
1599
- ctx.untrap();
1600
- }
1601
- if (strict && keys.length) {
1602
- result.splice(1, -1, this._lang.arrayInSet(this._lang.keys(ctx.vName), this._lang.array(keys)));
1603
- }
1604
- return this._lang.and(result);
1605
- }
1606
- _compileStructuredRule(ctx, rules) {
1607
- const mapSymbol = Object.keys(rules).filter((x) => x.startsWith(M.MAP));
1608
- if (mapSymbol.length > 1) {
1609
- throw new SyntaxError("Only one '$.map' is allowed as rest-mapping.");
1610
- }
1611
- else if (mapSymbol.length === 0) {
1612
- return this._compileSimpleStructure(ctx, rules);
1613
- }
1614
- const result = [
1615
- this._lang.isStrucutre(ctx.vName, true)
1616
- ];
1617
- ctx.trap();
1618
- const CLOSURE_ARG = ctx.vName;
1619
- const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
1620
- const FOR_KEY = this._lang.varName(ctx.vCursor++);
1621
- ctx.vName = this._lang.varName(ctx.vCursor++);
1622
- const CASES = [];
1623
- const keys = [];
1624
- for (let k in rules) {
1625
- ctx.trap(true);
1626
- let rule = rules[k];
1627
- let optional = false;
1628
- if (k.endsWith(I.IMPLICIT_SYMBOL)) {
1629
- optional = true;
1630
- k = k.slice(0, -1);
1631
- }
1632
- if (k.endsWith(I.KEY_LIST_SUFFIX)) {
1633
- k = k.slice(0, -I.KEY_LIST_SUFFIX.length);
1634
- rule = [M.LIST, rule];
1635
- }
1636
- else if (k.endsWith(I.KEY_MAP_SUFFIX)) {
1637
- k = k.slice(0, -I.KEY_MAP_SUFFIX.length);
1638
- rule = [M.MAP, rule];
1639
- }
1640
- else if (k.endsWith(I.KEY_STRICT_SUFFIX)) {
1641
- k = k.slice(0, -I.KEY_STRICT_SUFFIX.length);
1642
- rule = [M.STRICT, rule];
1643
- }
1644
- else if (k.endsWith(I.KEY_EQUAL_SUFFIX)) {
1645
- k = k.slice(0, -I.KEY_STRICT_SUFFIX.length);
1646
- rule = [M.EQUAL, rule];
1647
- }
1648
- else {
1649
- const matchResult = k.match(I.KEY_ARRAY_SUFFIX);
1650
- if (matchResult) {
1651
- k = k.slice(0, matchResult.index);
1652
- if (matchResult[3]) {
1653
- rule = [
1654
- M.ARRAY,
1655
- [
1656
- parseInt(matchResult[1]),
1657
- parseInt(matchResult[3])
1658
- ],
1659
- rule
1660
- ];
1661
- }
1662
- else if (matchResult[2]) {
1663
- rule = [M.ARRAY, [parseInt(matchResult[1])], rule];
1664
- }
1665
- else {
1666
- rule = [M.ARRAY, parseInt(matchResult[1]), rule];
1667
- }
1668
- }
1669
- }
1670
- if (k === M.MAP) {
1671
- CASES.push(this._lang.caseDefault(this._lang.ifThen(this._lang.not(this._compile(ctx, rule)), this._lang.returnValue(this._lang.literal(false)))));
1672
- }
1673
- else {
1674
- if (optional) {
1675
- if (this._isOrRule(rule)) {
1676
- rule.push(B.VOID);
1677
- }
1678
- else {
1679
- rule = [B.VOID, rule];
1680
- }
1681
- }
1682
- else {
1683
- keys.push(k);
1684
- }
1685
- CASES.push(this._lang.caseIf([this._lang.literal(k)], this._lang.ifThen(this._lang.not(this._compile(ctx, rule)), this._lang.returnValue(this._lang.literal(false)))));
1686
- }
1687
- ctx.untrap();
1688
- }
1689
- if (keys.length) {
1690
- result.push(this._lang.arrayInSet(this._lang.array(keys), this._lang.keys(CLOSURE_ARG)));
1691
- }
1692
- result.push(this._lang.closure([CLOSURE_PARAM], [CLOSURE_ARG], this._lang.series([
1693
- this._lang.forIn(CLOSURE_PARAM, FOR_KEY, ctx.vName, this._lang.switchCase(FOR_KEY, CASES)),
1694
- this._lang.returnValue(this._lang.literal(true))
1695
- ])));
1696
- ctx.untrap();
1697
- return this._lang.and(result);
1698
- }
1699
- _isOrRule(rule) {
1700
- return Array.isArray(rule) && (rule[0] === M.OR ||
1701
- typeof rule[0] !== "string" ||
1702
- !rule[0].startsWith(I.MODIFIER_PREFIX));
1703
- }
1704
- }
1705
- /**
1706
- * Create a compiler object.
1707
- *
1708
- * @param lang The language builder.
1709
- */
1710
- function createCompiler(lang) {
1711
- const bitc = new BuiltInTypeCompiler_1.BuiltInTypeCompiler(lang);
1712
- return new Compiler(lang, bitc, new FilterCompiler_1.FilterCompiler(lang, bitc));
1713
- }
1714
- exports.createCompiler = createCompiler;
1715
- });
1716
- /**
1717
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
1718
- *
1719
- * Licensed under the Apache License, Version 2.0 (the "License");
1720
- * you may not use this file except in compliance with the License.
1721
- * You may obtain a copy of the License at
1722
- *
1723
- * https://www.apache.org/licenses/LICENSE-2.0
1724
- *
1725
- * Unless required by applicable law or agreed to in writing, software
1726
- * distributed under the License is distributed on an "AS IS" BASIS,
1727
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1728
- * See the License for the specific language governing permissions and
1729
- * limitations under the License.
1730
- */
1731
- define("langs/JavaScript", ["require", "exports"], function (require, exports) {
1732
- "use strict";
1733
- Object.defineProperty(exports, "__esModule", { value: true });
1734
- class JavaScriptLanguage {
1735
- switchCase(expr, cases) {
1736
- return `switch (${expr}) { ${cases.join("")} }`;
1737
- }
1738
- caseIf(cond, expr) {
1739
- return `${cond.map((x) => `case ${x}:`).join(" ")} { ${expr} break; }`;
1740
- }
1741
- caseDefault(expr) {
1742
- return `default: { ${expr} break; }`;
1743
- }
1744
- lowerCase(a) {
1745
- return `${a}.toLowerCase()`;
1746
- }
1747
- array(v) {
1748
- return JSON.stringify(v);
1749
- }
1750
- arrayInSet(a, b) {
1751
- return `(function(a, b) {
1752
- return Array.from(new Set(a.concat(b))).length === b.length;
1753
- })(${a}, ${b})`;
1754
- }
1755
- instr(expr, match) {
1756
- return `${expr}.includes(${match})`;
1757
- }
1758
- call(fnName, ...args) {
1759
- return `${fnName}(${args.join(",")})`;
1760
- }
1761
- startsWith(expr, match) {
1762
- return `${expr}.startsWith(${match})`;
1763
- }
1764
- endsWith(expr, match) {
1765
- return `${expr}.endsWith(${match})`;
1766
- }
1767
- varName(index) {
1768
- return `v_${index}`;
1769
- }
1770
- _dereplicate(conds) {
1771
- return Array.from(new Set(conds));
1772
- }
1773
- ifElseOp(cond, a, b) {
1774
- return `(${cond}) ? ${a} : ${b}`;
1775
- }
1776
- or(conditions) {
1777
- if (conditions.length === 1) {
1778
- return conditions[0];
1779
- }
1780
- conditions = this._dereplicate(conditions.filter((x) => x !== "true"));
1781
- if (!conditions.length) {
1782
- return "true";
1783
- }
1784
- return `${conditions.map((x) => `(${x})`).join(" || ")}`;
1785
- }
1786
- and(conditions) {
1787
- if (conditions.length === 1) {
1788
- return conditions[0];
1789
- }
1790
- conditions = this._dereplicate(conditions.filter((x) => x !== "true"));
1791
- if (!conditions.length) {
1792
- return "true";
1793
- }
1794
- return `${conditions.map((x) => `(${x})`).join(" && ")}`;
1795
- }
1796
- eq(a, b) {
1797
- return `${a} === ${b}`;
1798
- }
1799
- ne(a, b) {
1800
- return `${a} !== ${b}`;
1801
- }
1802
- gt(a, b) {
1803
- return `${a} > ${b}`;
1804
- }
1805
- gte(a, b) {
1806
- return `${a} >= ${b}`;
1807
- }
1808
- lt(a, b) {
1809
- return `${a} < ${b}`;
1810
- }
1811
- lte(a, b) {
1812
- return `${a} <= ${b}`;
1813
- }
1814
- not(a) {
1815
- return `!(${a})`;
1816
- }
1817
- literal(val) {
1818
- return JSON.stringify(val);
1819
- }
1820
- modOf(a, b) {
1821
- return `${a} % ${b}`;
1822
- }
1823
- matchRegExp(expr, regExp) {
1824
- let m = regExp.match(/^\/(.+)\/([a-z]*)$/i);
1825
- if (m) {
1826
- return `/${m[1]}/${m[2] || ""}.test(${expr})`;
1827
- }
1828
- return `/${regExp}/.test(${expr})`;
1829
- }
1830
- isNull(vn, positive = true) {
1831
- return `${vn} ${this._equal(positive)} null`;
1832
- }
1833
- isUndefined(vn, positive = true) {
1834
- return `${vn} ${this._equal(positive)} undefined`;
1835
- }
1836
- _equal(positive = true) {
1837
- return positive ? "===" : "!==";
1838
- }
1839
- _not(positive = true) {
1840
- return positive ? "" : "!";
1841
- }
1842
- isString(vn, positive = true) {
1843
- return `typeof ${vn} ${this._equal(positive)} "string"`;
1844
- }
1845
- isStrucutre(vn, positive = true) {
1846
- return positive ?
1847
- `(typeof ${vn} === "object" && ${vn} !== null && !Array.isArray(${vn}))` :
1848
- `(typeof ${vn} !== "object" || ${vn} === null || Array.isArray(${vn}))`;
1849
- }
1850
- isInteger(vn, positive = true) {
1851
- return `${this._not(positive)}Number.isInteger(${vn})`;
1852
- }
1853
- isNumber(vn, positive = true) {
1854
- return positive ?
1855
- `typeof ${vn} === "number" && Number.isFinite(${vn}) && !Number.isNaN(${vn})` :
1856
- `typeof ${vn} !== "number" || !Number.isFinite(${vn}) || Number.isNaN(${vn})`;
1857
- }
1858
- isNumeric(vn, positive = true) {
1859
- return positive ? this.or([
1860
- this.isNumber(vn, true),
1861
- this.and([
1862
- this.isString(vn, true),
1863
- this.matchRegExp(vn, "^[+-]?\\d+(\\.\\d+)?$")
1864
- ])
1865
- ]) : this.and([
1866
- this.isNumber(vn, false),
1867
- this.or([
1868
- this.isString(vn, false),
1869
- this.not(this.matchRegExp(vn, "^[+-]?\\d+(\\.\\d+)?$"))
1870
- ])
1871
- ]);
1872
- }
1873
- isArray(vn, positive = true) {
1874
- return `${this._not(positive)}Array.isArray(${vn})`;
1875
- }
1876
- isBoolean(vn, positive = true) {
1877
- return `typeof ${vn} ${this._equal(positive)} "boolean"`;
1878
- }
1879
- arrayLength(vn) {
1880
- return `${vn}.length`;
1881
- }
1882
- stringLength(vn) {
1883
- return `${vn}.length`;
1884
- }
1885
- keys(vn) {
1886
- return `Object.keys(${vn})`;
1887
- }
1888
- forEach(an, it, body) {
1889
- return `for (const ${it} of ${an}) {
1890
- ${body}
1891
- }`;
1892
- }
1893
- series(statements) {
1894
- return statements.map((s) => s.endsWith(";") ? s : `${s};`).join("");
1895
- }
1896
- ifThen(condition, ifBody, elseBody) {
1897
- if (elseBody) {
1898
- return `if (${condition}) {
1899
- ${ifBody}
1900
- } else {
1901
- ${elseBody}
1902
- }`;
1903
- }
1904
- return `if (${condition}) { ${ifBody} }`;
1905
- }
1906
- forIn(o, k, i, body) {
1907
- return `for (const ${k} in ${o}) { const ${i} = ${o}[${k}]; ${body} }`;
1908
- }
1909
- fieldIndex(o, k) {
1910
- return `${o}[${k}]`;
1911
- }
1912
- str2Int(expr) {
1913
- return `parseInt(${expr})`;
1914
- }
1915
- str2Float(expr) {
1916
- return `parseFloat(${expr})`;
1917
- }
1918
- str2Bool(expr) {
1919
- return `(${expr} === "true" ? true : (${expr} === "false" ? false : null))`;
1920
- }
1921
- arraySlice(arrayName, start, end) {
1922
- if (end !== undefined) {
1923
- return `${arrayName}.slice(${start}, ${end})`;
1924
- }
1925
- return `${arrayName}.slice(${start})`;
1926
- }
1927
- arrayIndex(a, i) {
1928
- return `${a}[${i}]`;
1929
- }
1930
- get literalFalse() {
1931
- return `false`;
1932
- }
1933
- get literalTrue() {
1934
- return `true`;
1935
- }
1936
- get maxSafeInteger() {
1937
- return "0X1FFFFFFFFFFFFF";
1938
- }
1939
- get minSafeInteger() {
1940
- return "-0X1FFFFFFFFFFFFF";
1941
- }
1942
- isTrueValue(vn) {
1943
- return `!!${vn}`;
1944
- }
1945
- isFalseValue(vn) {
1946
- return `!${vn}`;
1947
- }
1948
- returnValue(vn) {
1949
- return `return ${vn};`;
1950
- }
1951
- closure(params, args, body) {
1952
- return `(function(${params.join(", ")}) {
1953
- ${body}
1954
- })(${args.join(", ")})`;
1955
- }
1956
- }
1957
- /**
1958
- * Create a language builder object for JavaScript.
1959
- */
1960
- function createJavaScriptLanguageBuilder() {
1961
- return new JavaScriptLanguage();
1962
- }
1963
- exports.createJavaScriptLanguageBuilder = createJavaScriptLanguageBuilder;
1964
- });
1965
- /**
1966
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
1967
- *
1968
- * Licensed under the Apache License, Version 2.0 (the "License");
1969
- * you may not use this file except in compliance with the License.
1970
- * You may obtain a copy of the License at
1971
- *
1972
- * https://www.apache.org/licenses/LICENSE-2.0
1973
- *
1974
- * Unless required by applicable law or agreed to in writing, software
1975
- * distributed under the License is distributed on an "AS IS" BASIS,
1976
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1977
- * See the License for the specific language governing permissions and
1978
- * limitations under the License.
1979
- */
1980
- define("InlineCompiler", ["require", "exports", "Compiler", "langs/JavaScript"], function (require, exports, Compiler_1, JavaScript_1) {
1981
- "use strict";
1982
- Object.defineProperty(exports, "__esModule", { value: true });
1983
- class InlineCompiler {
1984
- constructor() {
1985
- this._defTypes = {};
1986
- this._missingTypes = {};
1987
- const lang = JavaScript_1.createJavaScriptLanguageBuilder();
1988
- this._compiler = Compiler_1.createCompiler(lang);
1989
- }
1990
- compile(options) {
1991
- const result = this._compiler.compile(options);
1992
- this._preapreDefinedTypes(result.referredTypes, options.stopOnEntry);
1993
- return this._wrapCheckerCode(result, options.stopOnEntry);
1994
- }
1995
- _preapreDefinedTypes(types, stopOnEntry) {
1996
- for (let x of types) {
1997
- if (this._defTypes[x]) {
1998
- continue;
1999
- }
2000
- const info = this._compiler.getPredefinedType(x);
2001
- if (!info) {
2002
- this._missingTypes[x] = true;
2003
- continue;
2004
- }
2005
- this._defTypes[x] = this._wrapCheckerCode(info, stopOnEntry);
2006
- this._preapreDefinedTypes(info.referredTypes);
2007
- delete this._missingTypes[x];
2008
- }
2009
- }
2010
- detectUndefinedTypes() {
2011
- return Object.keys(this._missingTypes);
2012
- }
2013
- hasPredefinedType(name) {
2014
- return !!this._defTypes[name];
2015
- }
2016
- getPredefinedType(name) {
2017
- if (!this._defTypes[name]) {
2018
- throw new Error(`Pre-defined type "${name}" doesn't exist.`);
2019
- }
2020
- return this._defTypes[name];
2021
- }
2022
- _wrapCheckerCode(info, stopOnEntry = false) {
2023
- const soe = stopOnEntry ? "debugger;" : "";
2024
- return (new Function(info.typeSlotName, `return function(${info.arguments[0].name}) {${soe}
2025
-
2026
- return ${info.source};
2027
- };`))(this._defTypes);
2028
- }
2029
- }
2030
- /**
2031
- * Create a compiler object that compiles the rule into JavaScript lambda code.
2032
- */
2033
- function createInlineCompiler() {
2034
- return new InlineCompiler();
2035
- }
2036
- exports.createInlineCompiler = createInlineCompiler;
2037
- });
2038
- /**
2039
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2040
- *
2041
- * Licensed under the Apache License, Version 2.0 (the "License");
2042
- * you may not use this file except in compliance with the License.
2043
- * You may obtain a copy of the License at
2044
- *
2045
- * https://www.apache.org/licenses/LICENSE-2.0
2046
- *
2047
- * Unless required by applicable law or agreed to in writing, software
2048
- * distributed under the License is distributed on an "AS IS" BASIS,
2049
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2050
- * See the License for the specific language governing permissions and
2051
- * limitations under the License.
2052
- */
2053
- define("index", ["require", "exports", "InlineCompiler", "langs/JavaScript", "Compiler"], function (require, exports, InlineCompiler_1, JavaScript_2, Compiler_2) {
2054
- "use strict";
2055
- function __export(m) {
2056
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
2057
- }
2058
- Object.defineProperty(exports, "__esModule", { value: true });
2059
- __export(InlineCompiler_1);
2060
- __export(JavaScript_2);
2061
- __export(Compiler_2);
2062
- });
2063
- //# sourceMappingURL=typeguard.amd.js.map