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