@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.
- package/CHANGES.md +15 -0
- package/lib/BuiltInTypeCompiler.d.ts +4 -4
- package/lib/BuiltInTypeCompiler.d.ts.map +1 -1
- package/lib/BuiltInTypeCompiler.js +167 -166
- package/lib/BuiltInTypeCompiler.js.map +1 -1
- package/lib/BuiltInTypes.d.ts +1 -1
- package/lib/BuiltInTypes.js +37 -36
- package/lib/BuiltInTypes.js.map +1 -1
- package/lib/Common.d.ts +13 -9
- package/lib/Common.d.ts.map +1 -1
- package/lib/Common.js +1 -1
- package/lib/Compiler.d.ts +2 -2
- package/lib/Compiler.d.ts.map +1 -1
- package/lib/Compiler.js +77 -72
- package/lib/Compiler.js.map +1 -1
- package/lib/Context.d.ts +2 -2
- package/lib/Context.js +3 -2
- package/lib/Context.js.map +1 -1
- package/lib/FilterCompiler.d.ts +5 -5
- package/lib/FilterCompiler.d.ts.map +1 -1
- package/lib/FilterCompiler.js +25 -24
- package/lib/FilterCompiler.js.map +1 -1
- package/lib/InlineCompiler.d.ts +12 -5
- package/lib/InlineCompiler.d.ts.map +1 -1
- package/lib/InlineCompiler.js +14 -5
- package/lib/InlineCompiler.js.map +1 -1
- package/lib/Internal.d.ts +2 -1
- package/lib/Internal.d.ts.map +1 -1
- package/lib/Internal.js +12 -10
- package/lib/Internal.js.map +1 -1
- package/lib/Modifiers.d.ts +1 -1
- package/lib/Modifiers.js +2 -1
- package/lib/Modifiers.js.map +1 -1
- package/lib/index.d.ts +5 -5
- package/lib/index.js +19 -7
- package/lib/index.js.map +1 -1
- package/lib/langs/JavaScript.d.ts +2 -2
- package/lib/langs/JavaScript.d.ts.map +1 -1
- package/lib/langs/JavaScript.js +30 -23
- package/lib/langs/JavaScript.js.map +1 -1
- package/package.json +18 -13
- package/src/{samples → examples}/quick-start.ts +22 -12
- package/src/lib/BuiltInTypeCompiler.ts +171 -171
- package/src/lib/BuiltInTypes.ts +36 -36
- package/src/lib/Common.ts +15 -10
- package/src/lib/Compiler.ts +213 -208
- package/src/lib/Context.ts +3 -3
- package/src/lib/FilterCompiler.ts +84 -84
- package/src/lib/InlineCompiler.ts +35 -14
- package/src/lib/Internal.ts +12 -10
- package/src/lib/Modifiers.ts +2 -2
- package/src/lib/index.ts +5 -5
- package/src/lib/langs/JavaScript.ts +34 -24
- package/src/test/00-all.ts +11 -9
- package/src/test/01-elemental-types.ts +1111 -1110
- package/src/test/02-array-and-list.ts +75 -75
- package/src/test/03-tuple.ts +87 -87
- package/src/test/04-from-string.ts +849 -848
- package/src/test/05-string-asserts.ts +422 -422
- package/src/test/06-structure.ts +107 -107
- package/src/test/07-modifiers.ts +151 -42
- package/src/test/08-map-and-dict.ts +46 -46
- package/src/test/09-exceptions.ts +67 -0
- package/src/test/abstracts.ts +52 -43
- package/dist/typeguard.amd.d.ts +0 -588
- package/dist/typeguard.amd.d.ts.map +0 -1
- package/dist/typeguard.amd.js +0 -2063
- package/dist/typeguard.amd.js.map +0 -1
- package/dist/typeguard.system.d.ts +0 -588
- package/dist/typeguard.system.d.ts.map +0 -1
- package/dist/typeguard.system.js +0 -2179
- package/dist/typeguard.system.js.map +0 -1
- package/tsconfig-amd.json +0 -72
- package/tsconfig-systemjs.json +0 -72
package/src/lib/Compiler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2022 Angus Fenying <fenying@litert.org>
|
|
3
3
|
*
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
* you may not use this file except in compliance with the License.
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import * as I from
|
|
18
|
-
import * as C from
|
|
19
|
-
import * as M from
|
|
20
|
-
import { Context } from
|
|
21
|
-
import * as B from
|
|
22
|
-
import { BuiltInTypeCompiler } from
|
|
23
|
-
import { FilterCompiler } from
|
|
17
|
+
import * as I from './Internal';
|
|
18
|
+
import * as C from './Common';
|
|
19
|
+
import * as M from './Modifiers';
|
|
20
|
+
import { Context } from './Context';
|
|
21
|
+
import * as B from './BuiltInTypes';
|
|
22
|
+
import { BuiltInTypeCompiler } from './BuiltInTypeCompiler';
|
|
23
|
+
import { FilterCompiler } from './FilterCompiler';
|
|
24
24
|
|
|
25
25
|
class Compiler
|
|
26
26
|
implements C.ICompiler {
|
|
@@ -28,9 +28,9 @@ implements C.ICompiler {
|
|
|
28
28
|
private _defTypes: Record<string, C.ICompileResult>;
|
|
29
29
|
|
|
30
30
|
public constructor(
|
|
31
|
-
private _lang: C.ILanguageBuilder,
|
|
32
|
-
private _builtInTypes: I.IBuiltInTypeCompiler,
|
|
33
|
-
private _filters: I.IFilterCompiler
|
|
31
|
+
private readonly _lang: C.ILanguageBuilder,
|
|
32
|
+
private readonly _builtInTypes: I.IBuiltInTypeCompiler,
|
|
33
|
+
private readonly _filters: I.IFilterCompiler
|
|
34
34
|
) {
|
|
35
35
|
this._defTypes = {};
|
|
36
36
|
}
|
|
@@ -50,8 +50,8 @@ implements C.ICompiler {
|
|
|
50
50
|
const referredTypes: Record<string, true> = {};
|
|
51
51
|
|
|
52
52
|
const ctx: I.IContext = new Context(
|
|
53
|
-
this._lang.varName(
|
|
54
|
-
this._lang.varName(
|
|
53
|
+
this._lang.varName('entry'),
|
|
54
|
+
this._lang.varName('types'),
|
|
55
55
|
referredTypes
|
|
56
56
|
);
|
|
57
57
|
|
|
@@ -68,10 +68,10 @@ implements C.ICompiler {
|
|
|
68
68
|
|
|
69
69
|
const ret: C.ICompileResult = {
|
|
70
70
|
|
|
71
|
-
source:
|
|
71
|
+
source: '',
|
|
72
72
|
arguments: [{
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
'name': ctx.vName,
|
|
74
|
+
'type': 'unknown'
|
|
75
75
|
}],
|
|
76
76
|
typeSlotName: ctx.typeSlotName,
|
|
77
77
|
referredTypes: []
|
|
@@ -91,82 +91,85 @@ implements C.ICompiler {
|
|
|
91
91
|
private _compile(ctx: I.IContext, rules: any): string {
|
|
92
92
|
|
|
93
93
|
switch (typeof rules) {
|
|
94
|
-
|
|
94
|
+
case 'string':
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
return this._compileStringRule(ctx, rules);
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
case 'boolean':
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return this._lang.or([
|
|
103
|
-
this._lang.eq(
|
|
104
|
-
ctx.vName,
|
|
105
|
-
this._lang.literal(rules)
|
|
106
|
-
),
|
|
107
|
-
this._lang.eq(
|
|
108
|
-
this._lang.str2Bool(ctx.vName),
|
|
109
|
-
this._lang.literal(rules)
|
|
110
|
-
)
|
|
111
|
-
]);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return this._lang.eq(
|
|
115
|
-
ctx.vName,
|
|
116
|
-
this._lang.literal(rules)
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
case "number":
|
|
120
|
-
|
|
121
|
-
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
122
|
-
|
|
123
|
-
return this._lang.or([
|
|
124
|
-
this._lang.eq(
|
|
125
|
-
ctx.vName,
|
|
126
|
-
this._lang.literal(rules)
|
|
127
|
-
),
|
|
128
|
-
this._lang.eq(
|
|
129
|
-
this._lang.str2Float(ctx.vName),
|
|
130
|
-
this._lang.literal(rules)
|
|
131
|
-
)
|
|
132
|
-
]);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return this._lang.eq(
|
|
136
|
-
ctx.vName,
|
|
137
|
-
this._lang.literal(rules)
|
|
138
|
-
);
|
|
100
|
+
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
139
101
|
|
|
140
|
-
|
|
102
|
+
return this._lang.or([
|
|
103
|
+
this._lang.eq(
|
|
104
|
+
ctx.vName,
|
|
105
|
+
this._lang.literal(rules)
|
|
106
|
+
),
|
|
107
|
+
this._lang.eq(
|
|
108
|
+
this._lang.str2Bool(ctx.vName),
|
|
109
|
+
this._lang.literal(rules)
|
|
110
|
+
)
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
141
113
|
|
|
142
|
-
|
|
114
|
+
return this._lang.eq(
|
|
115
|
+
ctx.vName,
|
|
116
|
+
this._lang.literal(rules)
|
|
117
|
+
);
|
|
143
118
|
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
else if (rules === null) {
|
|
119
|
+
case 'number':
|
|
147
120
|
|
|
148
121
|
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
149
122
|
|
|
150
123
|
return this._lang.or([
|
|
151
|
-
this._lang.isNull(ctx.vName, true),
|
|
152
124
|
this._lang.eq(
|
|
153
125
|
ctx.vName,
|
|
154
|
-
this._lang.literal(
|
|
126
|
+
this._lang.literal(rules)
|
|
127
|
+
),
|
|
128
|
+
this._lang.eq(
|
|
129
|
+
this._lang.str2Float(ctx.vName),
|
|
130
|
+
this._lang.literal(rules)
|
|
155
131
|
)
|
|
156
132
|
]);
|
|
157
133
|
}
|
|
158
134
|
|
|
159
|
-
return this._lang.
|
|
160
|
-
|
|
135
|
+
return this._lang.eq(
|
|
136
|
+
ctx.vName,
|
|
137
|
+
this._lang.literal(rules)
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
case 'object':
|
|
141
|
+
|
|
142
|
+
if (Array.isArray(rules)) {
|
|
161
143
|
|
|
162
|
-
|
|
144
|
+
return this._compileModifiedRule(ctx, rules);
|
|
145
|
+
}
|
|
146
|
+
else if (rules === null) {
|
|
147
|
+
|
|
148
|
+
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
163
149
|
|
|
164
|
-
|
|
150
|
+
return this._lang.or([
|
|
151
|
+
this._lang.isNull(ctx.vName, true),
|
|
152
|
+
this._lang.eq(
|
|
153
|
+
ctx.vName,
|
|
154
|
+
this._lang.literal('null')
|
|
155
|
+
)
|
|
156
|
+
]);
|
|
157
|
+
}
|
|
165
158
|
|
|
166
|
-
|
|
159
|
+
return this._lang.isNull(ctx.vName, true);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return this._compileStructuredRule(ctx, rules);
|
|
163
|
+
|
|
164
|
+
case 'undefined':
|
|
165
|
+
|
|
166
|
+
return this._lang.isUndefined(ctx.vName, true);
|
|
167
|
+
|
|
168
|
+
default:
|
|
169
|
+
break;
|
|
167
170
|
}
|
|
168
171
|
|
|
169
|
-
throw new TypeError(
|
|
172
|
+
throw new TypeError('Unknwn rules.');
|
|
170
173
|
}
|
|
171
174
|
|
|
172
175
|
private _compileStringRule(ctx: I.IContext, rule: string): string {
|
|
@@ -181,7 +184,7 @@ implements C.ICompiler {
|
|
|
181
184
|
]);
|
|
182
185
|
}
|
|
183
186
|
|
|
184
|
-
if (rule
|
|
187
|
+
if (rule.startsWith(I.IMPLICIT_SYMBOL)) {
|
|
185
188
|
|
|
186
189
|
return this._lang.or([
|
|
187
190
|
this._builtInTypes.compile(B.VOID, ctx, []),
|
|
@@ -189,21 +192,21 @@ implements C.ICompiler {
|
|
|
189
192
|
]);
|
|
190
193
|
}
|
|
191
194
|
|
|
192
|
-
if (rule
|
|
195
|
+
if (rule.startsWith(I.NEGATIVE_SYMBOL)) {
|
|
193
196
|
|
|
194
197
|
return this._lang.not(this._compileStringRule(ctx, rule.slice(1)));
|
|
195
198
|
}
|
|
196
199
|
|
|
197
|
-
let regResult: RegExpMatchArray | null;
|
|
200
|
+
let regResult: RegExpMatchArray | null = /\[\s*(\d*|\d+\s*,\s*\d*)\s*\]$/.exec(rule);
|
|
198
201
|
|
|
199
202
|
/**
|
|
200
203
|
* For rules like `xxx[123]` or `xxx[1,5]`.
|
|
201
204
|
*/
|
|
202
|
-
if (regResult
|
|
205
|
+
if (regResult) {
|
|
203
206
|
|
|
204
207
|
if (regResult[1]) {
|
|
205
208
|
|
|
206
|
-
|
|
209
|
+
const range = regResult[1].split(',').map((x) => parseInt(x.trim()));
|
|
207
210
|
|
|
208
211
|
if (range.length === 1) {
|
|
209
212
|
|
|
@@ -252,11 +255,13 @@ implements C.ICompiler {
|
|
|
252
255
|
]);
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
if (rule
|
|
258
|
+
if (rule.startsWith(I.PREDEF_TYPE_SYMBOL)) {
|
|
256
259
|
|
|
257
260
|
return this._usePredefinedType(ctx, rule.slice(1));
|
|
258
261
|
}
|
|
259
262
|
|
|
263
|
+
regResult = /^(\w+)(\(\s*(-?\d+(\.\d+)?)?\s*,?\s*(-?\d+(\.\d+)?)?\s*\))?$/.exec(rule);
|
|
264
|
+
|
|
260
265
|
/**
|
|
261
266
|
* For built-in-type rules like:
|
|
262
267
|
*
|
|
@@ -265,11 +270,11 @@ implements C.ICompiler {
|
|
|
265
270
|
* - `string`
|
|
266
271
|
* - `int(12, 34)`
|
|
267
272
|
*/
|
|
268
|
-
if (regResult
|
|
273
|
+
if (regResult) {
|
|
269
274
|
|
|
270
275
|
if (regResult[2]) {
|
|
271
276
|
|
|
272
|
-
const args = regResult[2].slice(1, -1).trim().split(
|
|
277
|
+
const args = regResult[2].slice(1, -1).trim().split(',').map(
|
|
273
278
|
(x) => parseFloat(x.trim())
|
|
274
279
|
);
|
|
275
280
|
|
|
@@ -287,7 +292,7 @@ implements C.ICompiler {
|
|
|
287
292
|
);
|
|
288
293
|
}
|
|
289
294
|
|
|
290
|
-
if (rule
|
|
295
|
+
if (rule.startsWith(I.FILTER_PREFIX)) {
|
|
291
296
|
|
|
292
297
|
return this._filters.compile(rule, ctx);
|
|
293
298
|
}
|
|
@@ -318,162 +323,162 @@ implements C.ICompiler {
|
|
|
318
323
|
rule: string
|
|
319
324
|
): string | false {
|
|
320
325
|
|
|
321
|
-
const assertRule =
|
|
326
|
+
const assertRule = /^:([-\w]+):/.exec(rule);
|
|
322
327
|
|
|
323
328
|
const offset = assertRule ? assertRule[1].length + 2 : 2;
|
|
324
329
|
|
|
325
|
-
switch ((assertRule
|
|
326
|
-
|
|
327
|
-
|
|
330
|
+
switch ((assertRule?.[1]) ?? rule.substr(0, 2)) {
|
|
331
|
+
case '==':
|
|
332
|
+
case 'equal':
|
|
328
333
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
334
|
+
return this._lang.eq(
|
|
335
|
+
ctx.vName,
|
|
336
|
+
this._lang.literal(rule.slice(offset))
|
|
337
|
+
);
|
|
333
338
|
|
|
334
|
-
|
|
335
|
-
|
|
339
|
+
case '%=':
|
|
340
|
+
case 'equal-i':
|
|
336
341
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
342
|
+
return this._lang.eq(
|
|
343
|
+
this._lang.lowerCase(ctx.vName),
|
|
344
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
345
|
+
);
|
|
341
346
|
|
|
342
|
-
|
|
343
|
-
|
|
347
|
+
case '!=':
|
|
348
|
+
case 'not-equal':
|
|
344
349
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
350
|
+
return this._lang.ne(
|
|
351
|
+
ctx.vName,
|
|
352
|
+
this._lang.literal(rule.slice(offset))
|
|
353
|
+
);
|
|
349
354
|
|
|
350
|
-
|
|
351
|
-
|
|
355
|
+
case '%!':
|
|
356
|
+
case 'not-equal-i':
|
|
352
357
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
358
|
+
return this._lang.ne(
|
|
359
|
+
this._lang.lowerCase(ctx.vName),
|
|
360
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
361
|
+
);
|
|
357
362
|
|
|
358
|
-
|
|
359
|
-
|
|
363
|
+
case '~=':
|
|
364
|
+
case 'match':
|
|
360
365
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
366
|
+
return this._lang.matchRegExp(
|
|
367
|
+
ctx.vName,
|
|
368
|
+
rule.slice(offset)
|
|
369
|
+
);
|
|
365
370
|
|
|
366
|
-
|
|
367
|
-
|
|
371
|
+
case '~!':
|
|
372
|
+
case 'not-match':
|
|
368
373
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
374
|
+
return this._lang.not(this._lang.matchRegExp(
|
|
375
|
+
ctx.vName,
|
|
376
|
+
rule.slice(offset)
|
|
377
|
+
));
|
|
373
378
|
|
|
374
|
-
|
|
375
|
-
|
|
379
|
+
case '?=':
|
|
380
|
+
case 'include':
|
|
376
381
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
382
|
+
return this._lang.instr(
|
|
383
|
+
ctx.vName,
|
|
384
|
+
this._lang.literal(rule.slice(offset))
|
|
385
|
+
);
|
|
381
386
|
|
|
382
|
-
|
|
383
|
-
|
|
387
|
+
case '?!':
|
|
388
|
+
case 'not-include':
|
|
384
389
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
390
|
+
return this._lang.not(this._lang.instr(
|
|
391
|
+
ctx.vName,
|
|
392
|
+
this._lang.literal(rule.slice(offset))
|
|
393
|
+
));
|
|
389
394
|
|
|
390
|
-
|
|
391
|
-
|
|
395
|
+
case '*=':
|
|
396
|
+
case 'include-i':
|
|
392
397
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
398
|
+
return this._lang.instr(
|
|
399
|
+
this._lang.lowerCase(ctx.vName),
|
|
400
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
401
|
+
);
|
|
397
402
|
|
|
398
|
-
|
|
399
|
-
|
|
403
|
+
case '*!':
|
|
404
|
+
case 'not-include-i':
|
|
400
405
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
406
|
+
return this._lang.not(this._lang.instr(
|
|
407
|
+
this._lang.lowerCase(ctx.vName),
|
|
408
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
409
|
+
));
|
|
405
410
|
|
|
406
|
-
|
|
407
|
-
|
|
411
|
+
case '^=':
|
|
412
|
+
case 'start-with':
|
|
408
413
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
414
|
+
return this._lang.startsWith(
|
|
415
|
+
ctx.vName,
|
|
416
|
+
this._lang.literal(rule.slice(offset))
|
|
417
|
+
);
|
|
413
418
|
|
|
414
|
-
|
|
419
|
+
case 'start-with-i':
|
|
415
420
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
421
|
+
return this._lang.startsWith(
|
|
422
|
+
this._lang.lowerCase(ctx.vName),
|
|
423
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
424
|
+
);
|
|
420
425
|
|
|
421
|
-
|
|
422
|
-
|
|
426
|
+
case '^!':
|
|
427
|
+
case 'not-start-with':
|
|
423
428
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
429
|
+
return this._lang.not(this._lang.startsWith(
|
|
430
|
+
ctx.vName,
|
|
431
|
+
this._lang.literal(rule.slice(offset))
|
|
432
|
+
));
|
|
428
433
|
|
|
429
|
-
|
|
434
|
+
case 'not-start-with-i':
|
|
430
435
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
436
|
+
return this._lang.not(this._lang.startsWith(
|
|
437
|
+
this._lang.lowerCase(ctx.vName),
|
|
438
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
439
|
+
));
|
|
435
440
|
|
|
436
|
-
|
|
437
|
-
|
|
441
|
+
case '$=':
|
|
442
|
+
case 'end-with':
|
|
438
443
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
444
|
+
return this._lang.endsWith(
|
|
445
|
+
ctx.vName,
|
|
446
|
+
this._lang.literal(rule.slice(offset))
|
|
447
|
+
);
|
|
443
448
|
|
|
444
|
-
|
|
449
|
+
case 'end-with-i':
|
|
445
450
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
451
|
+
return this._lang.endsWith(
|
|
452
|
+
this._lang.lowerCase(ctx.vName),
|
|
453
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
454
|
+
);
|
|
450
455
|
|
|
451
|
-
|
|
452
|
-
|
|
456
|
+
case '$!':
|
|
457
|
+
case 'not-end-with':
|
|
453
458
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
459
|
+
return this._lang.not(this._lang.endsWith(
|
|
460
|
+
ctx.vName,
|
|
461
|
+
this._lang.literal(rule.slice(offset))
|
|
462
|
+
));
|
|
458
463
|
|
|
459
|
-
|
|
464
|
+
case 'not-end-with-i':
|
|
460
465
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
466
|
+
return this._lang.not(this._lang.endsWith(
|
|
467
|
+
this._lang.lowerCase(ctx.vName),
|
|
468
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
469
|
+
));
|
|
465
470
|
|
|
466
|
-
|
|
471
|
+
default:
|
|
467
472
|
|
|
468
|
-
|
|
473
|
+
if (rule.startsWith('=')) {
|
|
469
474
|
|
|
470
|
-
|
|
471
|
-
|
|
475
|
+
return this._lang.eq(ctx.vName, this._lang.literal(rule.slice(1)));
|
|
476
|
+
}
|
|
472
477
|
|
|
473
|
-
|
|
478
|
+
if (rule.startsWith('~')) {
|
|
474
479
|
|
|
475
|
-
|
|
476
|
-
|
|
480
|
+
return this._lang.matchRegExp(ctx.vName, rule.slice(1));
|
|
481
|
+
}
|
|
477
482
|
}
|
|
478
483
|
|
|
479
484
|
return false;
|
|
@@ -483,14 +488,14 @@ implements C.ICompiler {
|
|
|
483
488
|
|
|
484
489
|
if (!rules.length) {
|
|
485
490
|
|
|
486
|
-
throw new TypeError(
|
|
491
|
+
throw new TypeError('Unknwon type "[]".');
|
|
487
492
|
}
|
|
488
493
|
|
|
489
494
|
/**
|
|
490
495
|
* By default, use OR modifier.
|
|
491
496
|
*/
|
|
492
497
|
if (
|
|
493
|
-
typeof rules[0] !==
|
|
498
|
+
typeof rules[0] !== 'string' ||
|
|
494
499
|
!rules[0].startsWith(I.MODIFIER_PREFIX)
|
|
495
500
|
) {
|
|
496
501
|
|
|
@@ -574,7 +579,7 @@ implements C.ICompiler {
|
|
|
574
579
|
|
|
575
580
|
private _compileModifierOR(ctx: I.IContext, rules: any[]): string {
|
|
576
581
|
|
|
577
|
-
|
|
582
|
+
const result: string[] = [];
|
|
578
583
|
|
|
579
584
|
for (const r of rules) {
|
|
580
585
|
|
|
@@ -791,18 +796,18 @@ implements C.ICompiler {
|
|
|
791
796
|
break;
|
|
792
797
|
}
|
|
793
798
|
|
|
794
|
-
if (typeof type ===
|
|
799
|
+
if (typeof type === 'string' && type.startsWith('...')) {
|
|
795
800
|
|
|
796
801
|
throw new TypeError(`Invalid syntax for tuple: ${JSON.stringify(rules)}`);
|
|
797
802
|
}
|
|
798
803
|
|
|
799
|
-
if (typeof types[0] ===
|
|
804
|
+
if (typeof types[0] === 'string' && types[0].startsWith('...')) {
|
|
800
805
|
|
|
801
806
|
ctx.trap();
|
|
802
807
|
|
|
803
808
|
dots = types.shift();
|
|
804
809
|
|
|
805
|
-
if (dots ===
|
|
810
|
+
if (dots === '...') {
|
|
806
811
|
|
|
807
812
|
/**
|
|
808
813
|
* No more elements because "..." means all rest elements.
|
|
@@ -814,7 +819,7 @@ implements C.ICompiler {
|
|
|
814
819
|
|
|
815
820
|
ctx.vName = this._lang.arraySlice(ctx.vName, i);
|
|
816
821
|
|
|
817
|
-
if (type !==
|
|
822
|
+
if (type !== 'any') {
|
|
818
823
|
|
|
819
824
|
result.push(this._compileModifierLIST(
|
|
820
825
|
ctx, type
|
|
@@ -880,7 +885,7 @@ implements C.ICompiler {
|
|
|
880
885
|
|
|
881
886
|
private _validateTypeName(name: unknown): void {
|
|
882
887
|
|
|
883
|
-
if (typeof name !==
|
|
888
|
+
if (typeof name !== 'string' || !I.RE_VALID_CUSTOM_TYPE_NAME.test(name)) {
|
|
884
889
|
|
|
885
890
|
throw new TypeError(`Invalid name ${
|
|
886
891
|
JSON.stringify(name)
|
|
@@ -986,7 +991,7 @@ implements C.ICompiler {
|
|
|
986
991
|
throw new SyntaxError(`Invalid dict ${JSON.stringify(rules)}.`);
|
|
987
992
|
}
|
|
988
993
|
|
|
989
|
-
|
|
994
|
+
const tmp: Record<string, string> = {};
|
|
990
995
|
|
|
991
996
|
const id = `${Date.now()}${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`;
|
|
992
997
|
|
|
@@ -997,9 +1002,9 @@ implements C.ICompiler {
|
|
|
997
1002
|
|
|
998
1003
|
const type = `${I.PREDEF_TYPE_SYMBOL}${this._lang.varName(id)}`;
|
|
999
1004
|
|
|
1000
|
-
for (
|
|
1005
|
+
for (const key of rules[0]) {
|
|
1001
1006
|
|
|
1002
|
-
if (typeof key !==
|
|
1007
|
+
if (typeof key !== 'string') {
|
|
1003
1008
|
|
|
1004
1009
|
throw new SyntaxError(`Invalid key ${JSON.stringify(key)} for dict.`);
|
|
1005
1010
|
}
|
|
@@ -1059,7 +1064,7 @@ implements C.ICompiler {
|
|
|
1059
1064
|
}
|
|
1060
1065
|
else {
|
|
1061
1066
|
|
|
1062
|
-
const matchResult =
|
|
1067
|
+
const matchResult = I.KEY_ARRAY_SUFFIX.exec(k);
|
|
1063
1068
|
|
|
1064
1069
|
if (matchResult) {
|
|
1065
1070
|
|
|
@@ -1132,7 +1137,7 @@ implements C.ICompiler {
|
|
|
1132
1137
|
|
|
1133
1138
|
if (mapSymbol.length > 1) {
|
|
1134
1139
|
|
|
1135
|
-
throw new SyntaxError(
|
|
1140
|
+
throw new SyntaxError('Only one \'$.map\' is allowed as rest-mapping.');
|
|
1136
1141
|
}
|
|
1137
1142
|
else if (mapSymbol.length === 0) {
|
|
1138
1143
|
|
|
@@ -1193,7 +1198,7 @@ implements C.ICompiler {
|
|
|
1193
1198
|
}
|
|
1194
1199
|
else {
|
|
1195
1200
|
|
|
1196
|
-
const matchResult =
|
|
1201
|
+
const matchResult = I.KEY_ARRAY_SUFFIX.exec(k);
|
|
1197
1202
|
|
|
1198
1203
|
if (matchResult) {
|
|
1199
1204
|
|
|
@@ -1291,7 +1296,7 @@ implements C.ICompiler {
|
|
|
1291
1296
|
|
|
1292
1297
|
return Array.isArray(rule) && (
|
|
1293
1298
|
rule[0] === M.OR ||
|
|
1294
|
-
typeof rule[0] !==
|
|
1299
|
+
typeof rule[0] !== 'string' ||
|
|
1295
1300
|
!rule[0].startsWith(I.MODIFIER_PREFIX)
|
|
1296
1301
|
);
|
|
1297
1302
|
}
|