@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.
- package/CHANGES.md +16 -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 +27 -10
- 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 +159 -102
- package/lib/Compiler.js.map +1 -1
- package/lib/Context.d.ts +6 -5
- package/lib/Context.d.ts.map +1 -1
- package/lib/Context.js +11 -7
- 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 +18 -6
- package/lib/InlineCompiler.js.map +1 -1
- package/lib/Internal.d.ts +6 -4
- 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 +55 -29
- package/lib/langs/JavaScript.js.map +1 -1
- package/package.json +17 -13
- package/src/examples/quick-start.ts +172 -0
- package/src/lib/BuiltInTypeCompiler.ts +171 -171
- package/src/lib/BuiltInTypes.ts +36 -36
- package/src/lib/Common.ts +49 -10
- package/src/lib/Compiler.ts +354 -247
- package/src/lib/Context.ts +11 -13
- package/src/lib/FilterCompiler.ts +84 -84
- package/src/lib/InlineCompiler.ts +41 -15
- package/src/lib/Internal.ts +17 -13
- package/src/lib/Modifiers.ts +2 -2
- package/src/lib/index.ts +5 -5
- package/src/lib/langs/JavaScript.ts +84 -31
- package/src/test/00-all.ts +10 -10
- 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 +30 -9
- package/src/test/abstracts.ts +83 -45
- package/dist/typeguard.amd.d.ts +0 -588
- package/dist/typeguard.amd.d.ts.map +0 -1
- package/dist/typeguard.amd.js +0 -2069
- 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 -2185
- package/dist/typeguard.system.js.map +0 -1
- package/src/samples/quick-start.ts +0 -52
- 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,23 +14,22 @@
|
|
|
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
|
-
class Compiler
|
|
26
|
-
implements C.ICompiler {
|
|
25
|
+
class Compiler implements C.ICompiler {
|
|
27
26
|
|
|
28
27
|
private _defTypes: Record<string, C.ICompileResult>;
|
|
29
28
|
|
|
30
29
|
public constructor(
|
|
31
|
-
private _lang: C.ILanguageBuilder,
|
|
32
|
-
private _builtInTypes: I.IBuiltInTypeCompiler,
|
|
33
|
-
private _filters: I.IFilterCompiler
|
|
30
|
+
private readonly _lang: C.ILanguageBuilder,
|
|
31
|
+
private readonly _builtInTypes: I.IBuiltInTypeCompiler,
|
|
32
|
+
private readonly _filters: I.IFilterCompiler
|
|
34
33
|
) {
|
|
35
34
|
this._defTypes = {};
|
|
36
35
|
}
|
|
@@ -45,13 +44,44 @@ implements C.ICompiler {
|
|
|
45
44
|
return null;
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
private _addTrace(ctx: I.IContext): string {
|
|
48
|
+
|
|
49
|
+
if (!ctx.vTraceName) {
|
|
50
|
+
|
|
51
|
+
return this._lang.literalFalse;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return this._lang.addTrace(
|
|
55
|
+
ctx.vTraceName,
|
|
56
|
+
ctx.vTracePrefix,
|
|
57
|
+
ctx.tracePath
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private _addTraceOr(ctx: I.IContext, expr: string, subPath: string = ''): string {
|
|
62
|
+
|
|
63
|
+
if (!ctx.vTraceName) {
|
|
64
|
+
|
|
65
|
+
return expr;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return this._lang.orAddTrace(
|
|
69
|
+
expr,
|
|
70
|
+
ctx.vTraceName,
|
|
71
|
+
ctx.vTracePrefix,
|
|
72
|
+
`${ctx.tracePath}${subPath}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
48
76
|
public compile(options: C.ICompileOptions): C.ICompileResult {
|
|
49
77
|
|
|
50
78
|
const referredTypes: Record<string, true> = {};
|
|
51
79
|
|
|
52
80
|
const ctx: I.IContext = new Context(
|
|
53
|
-
this._lang.varName(
|
|
54
|
-
this._lang.varName(
|
|
81
|
+
this._lang.varName('entry'),
|
|
82
|
+
options.traceErrors ? this._lang.varName('failedAsserts') : '',
|
|
83
|
+
options.traceErrors ? this._lang.varName('tracePrefix') : '',
|
|
84
|
+
this._lang.varName('types'),
|
|
55
85
|
referredTypes
|
|
56
86
|
);
|
|
57
87
|
|
|
@@ -68,15 +98,31 @@ implements C.ICompiler {
|
|
|
68
98
|
|
|
69
99
|
const ret: C.ICompileResult = {
|
|
70
100
|
|
|
71
|
-
source:
|
|
101
|
+
source: '',
|
|
72
102
|
arguments: [{
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
'name': ctx.vName,
|
|
104
|
+
'type': 'unknown',
|
|
105
|
+
'initial': ''
|
|
75
106
|
}],
|
|
76
107
|
typeSlotName: ctx.typeSlotName,
|
|
77
108
|
referredTypes: []
|
|
78
109
|
};
|
|
79
110
|
|
|
111
|
+
if (ctx.vTraceName) {
|
|
112
|
+
|
|
113
|
+
ret.arguments.push({
|
|
114
|
+
'name': ctx.vTraceName,
|
|
115
|
+
'type': 'string[]',
|
|
116
|
+
'initial': '[]'
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
ret.arguments.push({
|
|
120
|
+
'name': ctx.vTracePrefix,
|
|
121
|
+
'type': 'string',
|
|
122
|
+
'initial': this._lang.literal('data')
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
80
126
|
ret.source = this._compile(
|
|
81
127
|
ctx,
|
|
82
128
|
options.rule
|
|
@@ -91,82 +137,85 @@ implements C.ICompiler {
|
|
|
91
137
|
private _compile(ctx: I.IContext, rules: any): string {
|
|
92
138
|
|
|
93
139
|
switch (typeof rules) {
|
|
94
|
-
|
|
140
|
+
case 'string':
|
|
95
141
|
|
|
96
|
-
|
|
142
|
+
return this._compileStringRule(ctx, rules);
|
|
97
143
|
|
|
98
|
-
|
|
144
|
+
case 'boolean':
|
|
99
145
|
|
|
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
|
-
);
|
|
146
|
+
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
return this._lang.or([
|
|
149
|
+
this._lang.eq(
|
|
150
|
+
ctx.vName,
|
|
151
|
+
this._lang.literal(rules)
|
|
152
|
+
),
|
|
153
|
+
this._lang.eq(
|
|
154
|
+
this._lang.str2Bool(ctx.vName),
|
|
155
|
+
this._lang.literal(rules)
|
|
156
|
+
)
|
|
157
|
+
]);
|
|
158
|
+
}
|
|
141
159
|
|
|
142
|
-
|
|
160
|
+
return this._lang.eq(
|
|
161
|
+
ctx.vName,
|
|
162
|
+
this._lang.literal(rules)
|
|
163
|
+
);
|
|
143
164
|
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
else if (rules === null) {
|
|
165
|
+
case 'number':
|
|
147
166
|
|
|
148
167
|
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
149
168
|
|
|
150
169
|
return this._lang.or([
|
|
151
|
-
this._lang.isNull(ctx.vName, true),
|
|
152
170
|
this._lang.eq(
|
|
153
171
|
ctx.vName,
|
|
154
|
-
this._lang.literal(
|
|
172
|
+
this._lang.literal(rules)
|
|
173
|
+
),
|
|
174
|
+
this._lang.eq(
|
|
175
|
+
this._lang.str2Float(ctx.vName),
|
|
176
|
+
this._lang.literal(rules)
|
|
155
177
|
)
|
|
156
178
|
]);
|
|
157
179
|
}
|
|
158
180
|
|
|
159
|
-
return this._lang.
|
|
160
|
-
|
|
181
|
+
return this._lang.eq(
|
|
182
|
+
ctx.vName,
|
|
183
|
+
this._lang.literal(rules)
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
case 'object':
|
|
161
187
|
|
|
162
|
-
|
|
188
|
+
if (Array.isArray(rules)) {
|
|
163
189
|
|
|
164
|
-
|
|
190
|
+
return this._compileModifiedRule(ctx, rules);
|
|
191
|
+
}
|
|
192
|
+
else if (rules === null) {
|
|
193
|
+
|
|
194
|
+
if (ctx.flags[I.EFlags.FROM_STRING]) {
|
|
195
|
+
|
|
196
|
+
return this._lang.or([
|
|
197
|
+
this._lang.isNull(ctx.vName, true),
|
|
198
|
+
this._lang.eq(
|
|
199
|
+
ctx.vName,
|
|
200
|
+
this._lang.literal('null')
|
|
201
|
+
)
|
|
202
|
+
]);
|
|
203
|
+
}
|
|
165
204
|
|
|
166
|
-
|
|
205
|
+
return this._lang.isNull(ctx.vName, true);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return this._compileStructuredRule(ctx, rules);
|
|
209
|
+
|
|
210
|
+
case 'undefined':
|
|
211
|
+
|
|
212
|
+
return this._lang.isUndefined(ctx.vName, true);
|
|
213
|
+
|
|
214
|
+
default:
|
|
215
|
+
break;
|
|
167
216
|
}
|
|
168
217
|
|
|
169
|
-
throw new TypeError(
|
|
218
|
+
throw new TypeError('Unknwn rules.');
|
|
170
219
|
}
|
|
171
220
|
|
|
172
221
|
private _compileStringRule(ctx: I.IContext, rule: string): string {
|
|
@@ -181,7 +230,7 @@ implements C.ICompiler {
|
|
|
181
230
|
]);
|
|
182
231
|
}
|
|
183
232
|
|
|
184
|
-
if (rule
|
|
233
|
+
if (rule.startsWith(I.IMPLICIT_SYMBOL)) {
|
|
185
234
|
|
|
186
235
|
return this._lang.or([
|
|
187
236
|
this._builtInTypes.compile(B.VOID, ctx, []),
|
|
@@ -189,61 +238,73 @@ implements C.ICompiler {
|
|
|
189
238
|
]);
|
|
190
239
|
}
|
|
191
240
|
|
|
192
|
-
if (rule
|
|
241
|
+
if (rule.startsWith(I.NEGATIVE_SYMBOL)) {
|
|
193
242
|
|
|
194
243
|
return this._lang.not(this._compileStringRule(ctx, rule.slice(1)));
|
|
195
244
|
}
|
|
196
245
|
|
|
197
|
-
let regResult: RegExpMatchArray | null;
|
|
246
|
+
let regResult: RegExpMatchArray | null = /\[\s*(\d*|\d+\s*,\s*\d*)\s*\]$/.exec(rule);
|
|
198
247
|
|
|
199
248
|
/**
|
|
200
|
-
* For rules like `xxx[123]` or `xxx[1,5]`.
|
|
249
|
+
* For rules like `xxx[123]` or `xxx[1,5]` or `xxx[1,]`.
|
|
201
250
|
*/
|
|
202
|
-
if (regResult
|
|
251
|
+
if (regResult) {
|
|
203
252
|
|
|
204
253
|
if (regResult[1]) {
|
|
205
254
|
|
|
206
|
-
|
|
255
|
+
const range = regResult[1].split(',').map((x) => parseInt(x.trim()));
|
|
207
256
|
|
|
208
257
|
if (range.length === 1) {
|
|
209
258
|
|
|
259
|
+
/**
|
|
260
|
+
* For rules like `xxx[123]`.
|
|
261
|
+
*/
|
|
210
262
|
return this._compileModifiedRule(ctx, [
|
|
211
263
|
M.ARRAY,
|
|
212
264
|
range[0],
|
|
213
|
-
rule.
|
|
265
|
+
rule.slice(0, regResult.index)
|
|
214
266
|
]);
|
|
215
267
|
}
|
|
216
268
|
else if (Number.isNaN(range[1])) {
|
|
217
269
|
|
|
270
|
+
/**
|
|
271
|
+
* For rules like `xxx[1,]`.
|
|
272
|
+
*/
|
|
218
273
|
return this._compileModifiedRule(ctx, [
|
|
219
274
|
M.ARRAY,
|
|
220
275
|
[range[0]],
|
|
221
|
-
rule.
|
|
276
|
+
rule.slice(0, regResult.index)
|
|
222
277
|
]);
|
|
223
278
|
}
|
|
224
279
|
else {
|
|
225
280
|
|
|
281
|
+
/**
|
|
282
|
+
* For rules like `xxx[1,5]`.
|
|
283
|
+
*/
|
|
226
284
|
return this._compileModifiedRule(ctx, [
|
|
227
285
|
M.ARRAY,
|
|
228
286
|
range,
|
|
229
|
-
rule.
|
|
287
|
+
rule.slice(0, regResult.index)
|
|
230
288
|
]);
|
|
231
289
|
}
|
|
232
290
|
}
|
|
233
291
|
else {
|
|
234
292
|
|
|
293
|
+
/**
|
|
294
|
+
* For rules like `xxx[]`.
|
|
295
|
+
*/
|
|
235
296
|
return this._compileModifiedRule(ctx, [
|
|
236
297
|
M.LIST,
|
|
237
|
-
rule.
|
|
298
|
+
rule.slice(0, regResult.index)
|
|
238
299
|
]);
|
|
239
300
|
}
|
|
240
301
|
}
|
|
241
302
|
|
|
242
|
-
/**
|
|
243
|
-
* For rules like `xxx{}`.
|
|
244
|
-
*/
|
|
245
303
|
if (rule.endsWith(I.MAP_SUFFIX)) {
|
|
246
304
|
|
|
305
|
+
/**
|
|
306
|
+
* For rules like `xxx{}`.
|
|
307
|
+
*/
|
|
247
308
|
return this._lang.and([
|
|
248
309
|
this._compileModifiedRule(ctx, [
|
|
249
310
|
M.MAP,
|
|
@@ -252,11 +313,13 @@ implements C.ICompiler {
|
|
|
252
313
|
]);
|
|
253
314
|
}
|
|
254
315
|
|
|
255
|
-
if (rule
|
|
316
|
+
if (rule.startsWith(I.PREDEF_TYPE_SYMBOL)) {
|
|
256
317
|
|
|
257
318
|
return this._usePredefinedType(ctx, rule.slice(1));
|
|
258
319
|
}
|
|
259
320
|
|
|
321
|
+
regResult = /^(\w+)(\(\s*(-?\d+(\.\d+)?)?\s*,?\s*(-?\d+(\.\d+)?)?\s*\))?$/.exec(rule);
|
|
322
|
+
|
|
260
323
|
/**
|
|
261
324
|
* For built-in-type rules like:
|
|
262
325
|
*
|
|
@@ -265,11 +328,11 @@ implements C.ICompiler {
|
|
|
265
328
|
* - `string`
|
|
266
329
|
* - `int(12, 34)`
|
|
267
330
|
*/
|
|
268
|
-
if (regResult
|
|
331
|
+
if (regResult) {
|
|
269
332
|
|
|
270
333
|
if (regResult[2]) {
|
|
271
334
|
|
|
272
|
-
const args = regResult[2].slice(1, -1).trim().split(
|
|
335
|
+
const args = regResult[2].slice(1, -1).trim().split(',').map(
|
|
273
336
|
(x) => parseFloat(x.trim())
|
|
274
337
|
);
|
|
275
338
|
|
|
@@ -287,7 +350,7 @@ implements C.ICompiler {
|
|
|
287
350
|
);
|
|
288
351
|
}
|
|
289
352
|
|
|
290
|
-
if (rule
|
|
353
|
+
if (rule.startsWith(I.FILTER_PREFIX)) {
|
|
291
354
|
|
|
292
355
|
return this._filters.compile(rule, ctx);
|
|
293
356
|
}
|
|
@@ -318,162 +381,162 @@ implements C.ICompiler {
|
|
|
318
381
|
rule: string
|
|
319
382
|
): string | false {
|
|
320
383
|
|
|
321
|
-
const assertRule =
|
|
384
|
+
const assertRule = /^:([-\w]+):/.exec(rule);
|
|
322
385
|
|
|
323
386
|
const offset = assertRule ? assertRule[1].length + 2 : 2;
|
|
324
387
|
|
|
325
|
-
switch ((assertRule
|
|
326
|
-
|
|
327
|
-
|
|
388
|
+
switch ((assertRule?.[1]) ?? rule.slice(0, 2)) {
|
|
389
|
+
case '==':
|
|
390
|
+
case 'equal':
|
|
328
391
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
392
|
+
return this._lang.eq(
|
|
393
|
+
ctx.vName,
|
|
394
|
+
this._lang.literal(rule.slice(offset))
|
|
395
|
+
);
|
|
333
396
|
|
|
334
|
-
|
|
335
|
-
|
|
397
|
+
case '%=':
|
|
398
|
+
case 'equal-i':
|
|
336
399
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
400
|
+
return this._lang.eq(
|
|
401
|
+
this._lang.lowerCase(ctx.vName),
|
|
402
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
403
|
+
);
|
|
341
404
|
|
|
342
|
-
|
|
343
|
-
|
|
405
|
+
case '!=':
|
|
406
|
+
case 'not-equal':
|
|
344
407
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
408
|
+
return this._lang.ne(
|
|
409
|
+
ctx.vName,
|
|
410
|
+
this._lang.literal(rule.slice(offset))
|
|
411
|
+
);
|
|
349
412
|
|
|
350
|
-
|
|
351
|
-
|
|
413
|
+
case '%!':
|
|
414
|
+
case 'not-equal-i':
|
|
352
415
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
416
|
+
return this._lang.ne(
|
|
417
|
+
this._lang.lowerCase(ctx.vName),
|
|
418
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
419
|
+
);
|
|
357
420
|
|
|
358
|
-
|
|
359
|
-
|
|
421
|
+
case '~=':
|
|
422
|
+
case 'match':
|
|
360
423
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
424
|
+
return this._lang.matchRegExp(
|
|
425
|
+
ctx.vName,
|
|
426
|
+
rule.slice(offset)
|
|
427
|
+
);
|
|
365
428
|
|
|
366
|
-
|
|
367
|
-
|
|
429
|
+
case '~!':
|
|
430
|
+
case 'not-match':
|
|
368
431
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
432
|
+
return this._lang.not(this._lang.matchRegExp(
|
|
433
|
+
ctx.vName,
|
|
434
|
+
rule.slice(offset)
|
|
435
|
+
));
|
|
373
436
|
|
|
374
|
-
|
|
375
|
-
|
|
437
|
+
case '?=':
|
|
438
|
+
case 'include':
|
|
376
439
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
440
|
+
return this._lang.instr(
|
|
441
|
+
ctx.vName,
|
|
442
|
+
this._lang.literal(rule.slice(offset))
|
|
443
|
+
);
|
|
381
444
|
|
|
382
|
-
|
|
383
|
-
|
|
445
|
+
case '?!':
|
|
446
|
+
case 'not-include':
|
|
384
447
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
448
|
+
return this._lang.not(this._lang.instr(
|
|
449
|
+
ctx.vName,
|
|
450
|
+
this._lang.literal(rule.slice(offset))
|
|
451
|
+
));
|
|
389
452
|
|
|
390
|
-
|
|
391
|
-
|
|
453
|
+
case '*=':
|
|
454
|
+
case 'include-i':
|
|
392
455
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
456
|
+
return this._lang.instr(
|
|
457
|
+
this._lang.lowerCase(ctx.vName),
|
|
458
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
459
|
+
);
|
|
397
460
|
|
|
398
|
-
|
|
399
|
-
|
|
461
|
+
case '*!':
|
|
462
|
+
case 'not-include-i':
|
|
400
463
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
464
|
+
return this._lang.not(this._lang.instr(
|
|
465
|
+
this._lang.lowerCase(ctx.vName),
|
|
466
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
467
|
+
));
|
|
405
468
|
|
|
406
|
-
|
|
407
|
-
|
|
469
|
+
case '^=':
|
|
470
|
+
case 'start-with':
|
|
408
471
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
472
|
+
return this._lang.startsWith(
|
|
473
|
+
ctx.vName,
|
|
474
|
+
this._lang.literal(rule.slice(offset))
|
|
475
|
+
);
|
|
413
476
|
|
|
414
|
-
|
|
477
|
+
case 'start-with-i':
|
|
415
478
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
479
|
+
return this._lang.startsWith(
|
|
480
|
+
this._lang.lowerCase(ctx.vName),
|
|
481
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
482
|
+
);
|
|
420
483
|
|
|
421
|
-
|
|
422
|
-
|
|
484
|
+
case '^!':
|
|
485
|
+
case 'not-start-with':
|
|
423
486
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
487
|
+
return this._lang.not(this._lang.startsWith(
|
|
488
|
+
ctx.vName,
|
|
489
|
+
this._lang.literal(rule.slice(offset))
|
|
490
|
+
));
|
|
428
491
|
|
|
429
|
-
|
|
492
|
+
case 'not-start-with-i':
|
|
430
493
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
494
|
+
return this._lang.not(this._lang.startsWith(
|
|
495
|
+
this._lang.lowerCase(ctx.vName),
|
|
496
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
497
|
+
));
|
|
435
498
|
|
|
436
|
-
|
|
437
|
-
|
|
499
|
+
case '$=':
|
|
500
|
+
case 'end-with':
|
|
438
501
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
502
|
+
return this._lang.endsWith(
|
|
503
|
+
ctx.vName,
|
|
504
|
+
this._lang.literal(rule.slice(offset))
|
|
505
|
+
);
|
|
443
506
|
|
|
444
|
-
|
|
507
|
+
case 'end-with-i':
|
|
445
508
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
509
|
+
return this._lang.endsWith(
|
|
510
|
+
this._lang.lowerCase(ctx.vName),
|
|
511
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
512
|
+
);
|
|
450
513
|
|
|
451
|
-
|
|
452
|
-
|
|
514
|
+
case '$!':
|
|
515
|
+
case 'not-end-with':
|
|
453
516
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
517
|
+
return this._lang.not(this._lang.endsWith(
|
|
518
|
+
ctx.vName,
|
|
519
|
+
this._lang.literal(rule.slice(offset))
|
|
520
|
+
));
|
|
458
521
|
|
|
459
|
-
|
|
522
|
+
case 'not-end-with-i':
|
|
460
523
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
524
|
+
return this._lang.not(this._lang.endsWith(
|
|
525
|
+
this._lang.lowerCase(ctx.vName),
|
|
526
|
+
this._lang.literal(rule.slice(offset).toLowerCase())
|
|
527
|
+
));
|
|
465
528
|
|
|
466
|
-
|
|
529
|
+
default:
|
|
467
530
|
|
|
468
|
-
|
|
531
|
+
if (rule.startsWith('=')) {
|
|
469
532
|
|
|
470
|
-
|
|
471
|
-
|
|
533
|
+
return this._lang.eq(ctx.vName, this._lang.literal(rule.slice(1)));
|
|
534
|
+
}
|
|
472
535
|
|
|
473
|
-
|
|
536
|
+
if (rule.startsWith('~')) {
|
|
474
537
|
|
|
475
|
-
|
|
476
|
-
|
|
538
|
+
return this._lang.matchRegExp(ctx.vName, rule.slice(1));
|
|
539
|
+
}
|
|
477
540
|
}
|
|
478
541
|
|
|
479
542
|
return false;
|
|
@@ -483,14 +546,14 @@ implements C.ICompiler {
|
|
|
483
546
|
|
|
484
547
|
if (!rules.length) {
|
|
485
548
|
|
|
486
|
-
throw new TypeError(
|
|
549
|
+
throw new TypeError('Unknwon type "[]".');
|
|
487
550
|
}
|
|
488
551
|
|
|
489
552
|
/**
|
|
490
553
|
* By default, use OR modifier.
|
|
491
554
|
*/
|
|
492
555
|
if (
|
|
493
|
-
typeof rules[0] !==
|
|
556
|
+
typeof rules[0] !== 'string' ||
|
|
494
557
|
!rules[0].startsWith(I.MODIFIER_PREFIX)
|
|
495
558
|
) {
|
|
496
559
|
|
|
@@ -574,7 +637,7 @@ implements C.ICompiler {
|
|
|
574
637
|
|
|
575
638
|
private _compileModifierOR(ctx: I.IContext, rules: any[]): string {
|
|
576
639
|
|
|
577
|
-
|
|
640
|
+
const result: string[] = [];
|
|
578
641
|
|
|
579
642
|
for (const r of rules) {
|
|
580
643
|
|
|
@@ -595,7 +658,7 @@ implements C.ICompiler {
|
|
|
595
658
|
);
|
|
596
659
|
}
|
|
597
660
|
|
|
598
|
-
private _compileModifierLIST(ctx: I.IContext, rules: any[]): string {
|
|
661
|
+
private _compileModifierLIST(ctx: I.IContext, rules: any[], traceOffset: number = 0): string {
|
|
599
662
|
|
|
600
663
|
const result: string[] = [];
|
|
601
664
|
|
|
@@ -613,6 +676,10 @@ implements C.ICompiler {
|
|
|
613
676
|
const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
|
|
614
677
|
|
|
615
678
|
ctx.vName = this._lang.varName(ctx.vCursor++);
|
|
679
|
+
const vIter = this._lang.varName(ctx.vCursor++);
|
|
680
|
+
ctx.tracePath = `${ctx.tracePath}[${this._lang.numberTemplateVar(
|
|
681
|
+
traceOffset ? this._lang.add(traceOffset, vIter) : vIter
|
|
682
|
+
)}]`;
|
|
616
683
|
|
|
617
684
|
if (rules[0] !== B.ANY) {
|
|
618
685
|
|
|
@@ -621,9 +688,9 @@ implements C.ICompiler {
|
|
|
621
688
|
[CLOSURE_ARG],
|
|
622
689
|
this._lang.series([
|
|
623
690
|
this._lang.forEach(
|
|
624
|
-
CLOSURE_PARAM, ctx.vName, this._lang.ifThen(
|
|
691
|
+
CLOSURE_PARAM, vIter, ctx.vName, this._lang.ifThen(
|
|
625
692
|
this._lang.not(this._compile(ctx, rules)),
|
|
626
|
-
this._lang.returnValue(this.
|
|
693
|
+
this._lang.returnValue(this._addTrace(ctx))
|
|
627
694
|
)
|
|
628
695
|
),
|
|
629
696
|
this._lang.returnValue(this._lang.literal(true))
|
|
@@ -636,7 +703,7 @@ implements C.ICompiler {
|
|
|
636
703
|
return this._lang.and(result);
|
|
637
704
|
}
|
|
638
705
|
|
|
639
|
-
private _compileModifierARRAY(ctx: I.IContext, rules: any[]): string {
|
|
706
|
+
private _compileModifierARRAY(ctx: I.IContext, rules: any[], traceOffset: number = 0): string {
|
|
640
707
|
|
|
641
708
|
let a: number = 0;
|
|
642
709
|
let b: number = -1;
|
|
@@ -716,6 +783,10 @@ implements C.ICompiler {
|
|
|
716
783
|
const CLOSURE_PARAM = this._lang.varName(ctx.vCursor++);
|
|
717
784
|
|
|
718
785
|
ctx.vName = this._lang.varName(ctx.vCursor++);
|
|
786
|
+
const vIter = this._lang.varName(ctx.vCursor++);
|
|
787
|
+
ctx.tracePath = `${ctx.tracePath}[${this._lang.numberTemplateVar(
|
|
788
|
+
traceOffset ? this._lang.add(traceOffset, vIter) : vIter
|
|
789
|
+
)}]`;
|
|
719
790
|
|
|
720
791
|
switch (b) {
|
|
721
792
|
case -1: {
|
|
@@ -749,9 +820,9 @@ implements C.ICompiler {
|
|
|
749
820
|
[CLOSURE_ARG],
|
|
750
821
|
this._lang.series([
|
|
751
822
|
this._lang.forEach(
|
|
752
|
-
CLOSURE_PARAM, ctx.vName, this._lang.ifThen(
|
|
823
|
+
CLOSURE_PARAM, vIter, ctx.vName, this._lang.ifThen(
|
|
753
824
|
this._lang.not(this._compile(ctx, rules.slice(1))),
|
|
754
|
-
this._lang.returnValue(this.
|
|
825
|
+
this._lang.returnValue(this._addTrace(ctx))
|
|
755
826
|
)
|
|
756
827
|
),
|
|
757
828
|
this._lang.returnValue(this._lang.literal(true))
|
|
@@ -781,6 +852,7 @@ implements C.ICompiler {
|
|
|
781
852
|
|
|
782
853
|
const types = rules.slice();
|
|
783
854
|
let tupleLength = 0;
|
|
855
|
+
let tupleLengthMin = 0;
|
|
784
856
|
|
|
785
857
|
while (1) {
|
|
786
858
|
|
|
@@ -791,18 +863,18 @@ implements C.ICompiler {
|
|
|
791
863
|
break;
|
|
792
864
|
}
|
|
793
865
|
|
|
794
|
-
if (typeof type ===
|
|
866
|
+
if (typeof type === 'string' && type.startsWith('...')) {
|
|
795
867
|
|
|
796
868
|
throw new TypeError(`Invalid syntax for tuple: ${JSON.stringify(rules)}`);
|
|
797
869
|
}
|
|
798
870
|
|
|
799
|
-
if (typeof types[0] ===
|
|
871
|
+
if (typeof types[0] === 'string' && types[0].startsWith('...')) {
|
|
800
872
|
|
|
801
873
|
ctx.trap();
|
|
802
874
|
|
|
803
875
|
dots = types.shift();
|
|
804
876
|
|
|
805
|
-
if (dots ===
|
|
877
|
+
if (dots === '...') {
|
|
806
878
|
|
|
807
879
|
/**
|
|
808
880
|
* No more elements because "..." means all rest elements.
|
|
@@ -814,13 +886,14 @@ implements C.ICompiler {
|
|
|
814
886
|
|
|
815
887
|
ctx.vName = this._lang.arraySlice(ctx.vName, i);
|
|
816
888
|
|
|
817
|
-
if (type !==
|
|
889
|
+
if (type !== 'any') {
|
|
818
890
|
|
|
819
891
|
result.push(this._compileModifierLIST(
|
|
820
|
-
ctx, type
|
|
892
|
+
ctx, type, i
|
|
821
893
|
));
|
|
822
894
|
}
|
|
823
895
|
|
|
896
|
+
tupleLengthMin = tupleLength;
|
|
824
897
|
tupleLength = -1;
|
|
825
898
|
}
|
|
826
899
|
else if (!/^\d+$/.test(dots.slice(3))) {
|
|
@@ -831,22 +904,27 @@ implements C.ICompiler {
|
|
|
831
904
|
|
|
832
905
|
const length = parseInt(dots.slice(3));
|
|
833
906
|
|
|
834
|
-
if (length
|
|
907
|
+
if (length === 0) {
|
|
835
908
|
|
|
836
|
-
|
|
909
|
+
throw new TypeError(`Invalid syntax for tuple: ${dots}`);
|
|
910
|
+
}
|
|
911
|
+
else if (length === 1) {
|
|
837
912
|
|
|
838
|
-
|
|
913
|
+
const vName = ctx.vName;
|
|
839
914
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
915
|
+
ctx.tracePath = `${ctx.tracePath}[${i}]`;
|
|
916
|
+
ctx.vName = this._lang.arrayIndex(vName, i++);
|
|
917
|
+
result.push(this._addTraceOr(
|
|
918
|
+
ctx,
|
|
919
|
+
this._compile(ctx, type),
|
|
920
|
+
));
|
|
843
921
|
}
|
|
844
922
|
else {
|
|
845
923
|
|
|
846
924
|
ctx.vName = this._lang.arraySlice(ctx.vName, i, i + length);
|
|
847
925
|
|
|
848
926
|
result.push(this._compileModifierARRAY(
|
|
849
|
-
ctx, [length, type]
|
|
927
|
+
ctx, [length, type], i
|
|
850
928
|
));
|
|
851
929
|
|
|
852
930
|
i += length;
|
|
@@ -859,8 +937,12 @@ implements C.ICompiler {
|
|
|
859
937
|
|
|
860
938
|
ctx.trap(true);
|
|
861
939
|
|
|
940
|
+
ctx.tracePath = `${ctx.tracePath}[${i}]`;
|
|
862
941
|
ctx.vName = this._lang.arrayIndex(ctx.vName, i++);
|
|
863
|
-
result.push(this.
|
|
942
|
+
result.push(this._addTraceOr(
|
|
943
|
+
ctx,
|
|
944
|
+
this._compile(ctx, type),
|
|
945
|
+
));
|
|
864
946
|
tupleLength++;
|
|
865
947
|
}
|
|
866
948
|
|
|
@@ -869,9 +951,24 @@ implements C.ICompiler {
|
|
|
869
951
|
|
|
870
952
|
if (tupleLength >= 0) {
|
|
871
953
|
|
|
872
|
-
result.splice(1, -1, this.
|
|
873
|
-
|
|
874
|
-
|
|
954
|
+
result.splice(1, -1, this._addTraceOr(
|
|
955
|
+
ctx,
|
|
956
|
+
this._lang.eq(
|
|
957
|
+
this._lang.arrayLength(ctx.vName),
|
|
958
|
+
tupleLength
|
|
959
|
+
),
|
|
960
|
+
'.length'
|
|
961
|
+
));
|
|
962
|
+
}
|
|
963
|
+
else if (tupleLengthMin >= 0) {
|
|
964
|
+
|
|
965
|
+
result.splice(1, -1, this._addTraceOr(
|
|
966
|
+
ctx,
|
|
967
|
+
this._lang.gte(
|
|
968
|
+
this._lang.arrayLength(ctx.vName),
|
|
969
|
+
tupleLengthMin
|
|
970
|
+
),
|
|
971
|
+
'.length'
|
|
875
972
|
));
|
|
876
973
|
}
|
|
877
974
|
|
|
@@ -880,7 +977,7 @@ implements C.ICompiler {
|
|
|
880
977
|
|
|
881
978
|
private _validateTypeName(name: unknown): void {
|
|
882
979
|
|
|
883
|
-
if (typeof name !==
|
|
980
|
+
if (typeof name !== 'string' || !I.RE_VALID_CUSTOM_TYPE_NAME.test(name)) {
|
|
884
981
|
|
|
885
982
|
throw new TypeError(`Invalid name ${
|
|
886
983
|
JSON.stringify(name)
|
|
@@ -898,7 +995,8 @@ implements C.ICompiler {
|
|
|
898
995
|
}
|
|
899
996
|
|
|
900
997
|
this._defTypes[rules[0]] = this.compile({
|
|
901
|
-
rule: rules.slice(1)
|
|
998
|
+
rule: rules.slice(1),
|
|
999
|
+
traceErrors: !!ctx.vTraceName
|
|
902
1000
|
});
|
|
903
1001
|
|
|
904
1002
|
return this._usePredefinedType(ctx, rules[0]);
|
|
@@ -949,24 +1047,25 @@ implements C.ICompiler {
|
|
|
949
1047
|
|
|
950
1048
|
ctx.trap(true);
|
|
951
1049
|
|
|
952
|
-
const
|
|
1050
|
+
const vCArg = ctx.vName;
|
|
953
1051
|
|
|
954
|
-
const
|
|
1052
|
+
const vCParam = this._lang.varName(ctx.vCursor++);
|
|
955
1053
|
|
|
956
|
-
const
|
|
1054
|
+
const vKey = this._lang.varName(ctx.vCursor++);
|
|
957
1055
|
|
|
958
1056
|
ctx.vName = this._lang.varName(ctx.vCursor++);
|
|
1057
|
+
ctx.tracePath = `${ctx.tracePath}[${this._lang.stringTemplateVar(vKey)}]`;
|
|
959
1058
|
|
|
960
1059
|
const result = this._lang.and([
|
|
961
|
-
this._lang.isStrucutre(
|
|
1060
|
+
this._lang.isStrucutre(vCArg, true),
|
|
962
1061
|
this._lang.closure(
|
|
963
|
-
[
|
|
964
|
-
[
|
|
1062
|
+
[vCParam],
|
|
1063
|
+
[vCArg],
|
|
965
1064
|
this._lang.series([
|
|
966
1065
|
this._lang.forIn(
|
|
967
|
-
|
|
1066
|
+
vCParam, vKey, ctx.vName, this._lang.ifThen(
|
|
968
1067
|
this._lang.not(this._compile(ctx, rules)),
|
|
969
|
-
this._lang.returnValue(this.
|
|
1068
|
+
this._lang.returnValue(this._addTrace(ctx))
|
|
970
1069
|
)
|
|
971
1070
|
),
|
|
972
1071
|
this._lang.returnValue(this._lang.literal(true))
|
|
@@ -986,7 +1085,7 @@ implements C.ICompiler {
|
|
|
986
1085
|
throw new SyntaxError(`Invalid dict ${JSON.stringify(rules)}.`);
|
|
987
1086
|
}
|
|
988
1087
|
|
|
989
|
-
|
|
1088
|
+
const tmp: Record<string, string> = {};
|
|
990
1089
|
|
|
991
1090
|
const id = `${Date.now()}${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`;
|
|
992
1091
|
|
|
@@ -997,9 +1096,9 @@ implements C.ICompiler {
|
|
|
997
1096
|
|
|
998
1097
|
const type = `${I.PREDEF_TYPE_SYMBOL}${this._lang.varName(id)}`;
|
|
999
1098
|
|
|
1000
|
-
for (
|
|
1099
|
+
for (const key of rules[0]) {
|
|
1001
1100
|
|
|
1002
|
-
if (typeof key !==
|
|
1101
|
+
if (typeof key !== 'string') {
|
|
1003
1102
|
|
|
1004
1103
|
throw new SyntaxError(`Invalid key ${JSON.stringify(key)} for dict.`);
|
|
1005
1104
|
}
|
|
@@ -1018,7 +1117,11 @@ implements C.ICompiler {
|
|
|
1018
1117
|
const strict = !!ctx.flags[I.EFlags.STRICT];
|
|
1019
1118
|
|
|
1020
1119
|
const result: string[] = [
|
|
1021
|
-
this.
|
|
1120
|
+
this._addTraceOr(
|
|
1121
|
+
ctx,
|
|
1122
|
+
this._lang.isStrucutre(ctx.vName, true),
|
|
1123
|
+
'!object'
|
|
1124
|
+
)
|
|
1022
1125
|
];
|
|
1023
1126
|
|
|
1024
1127
|
const keys: string[] = [];
|
|
@@ -1059,7 +1162,7 @@ implements C.ICompiler {
|
|
|
1059
1162
|
}
|
|
1060
1163
|
else {
|
|
1061
1164
|
|
|
1062
|
-
const matchResult =
|
|
1165
|
+
const matchResult = I.KEY_ARRAY_SUFFIX.exec(k);
|
|
1063
1166
|
|
|
1064
1167
|
if (matchResult) {
|
|
1065
1168
|
|
|
@@ -1102,8 +1205,12 @@ implements C.ICompiler {
|
|
|
1102
1205
|
keys.push(k);
|
|
1103
1206
|
|
|
1104
1207
|
ctx.vName = this._lang.fieldIndex(ctx.vName, this._lang.literal(k));
|
|
1208
|
+
ctx.tracePath = `${ctx.tracePath}[${this._lang.literal(k)}]`;
|
|
1105
1209
|
|
|
1106
|
-
result.push(this.
|
|
1210
|
+
result.push(this._addTraceOr(
|
|
1211
|
+
ctx,
|
|
1212
|
+
this._compile(ctx, rule)
|
|
1213
|
+
));
|
|
1107
1214
|
|
|
1108
1215
|
ctx.untrap();
|
|
1109
1216
|
}
|
|
@@ -1132,7 +1239,7 @@ implements C.ICompiler {
|
|
|
1132
1239
|
|
|
1133
1240
|
if (mapSymbol.length > 1) {
|
|
1134
1241
|
|
|
1135
|
-
throw new SyntaxError(
|
|
1242
|
+
throw new SyntaxError('Only one \'$.map\' is allowed as rest-mapping.');
|
|
1136
1243
|
}
|
|
1137
1244
|
else if (mapSymbol.length === 0) {
|
|
1138
1245
|
|
|
@@ -1193,7 +1300,7 @@ implements C.ICompiler {
|
|
|
1193
1300
|
}
|
|
1194
1301
|
else {
|
|
1195
1302
|
|
|
1196
|
-
const matchResult =
|
|
1303
|
+
const matchResult = I.KEY_ARRAY_SUFFIX.exec(k);
|
|
1197
1304
|
|
|
1198
1305
|
if (matchResult) {
|
|
1199
1306
|
|
|
@@ -1291,7 +1398,7 @@ implements C.ICompiler {
|
|
|
1291
1398
|
|
|
1292
1399
|
return Array.isArray(rule) && (
|
|
1293
1400
|
rule[0] === M.OR ||
|
|
1294
|
-
typeof rule[0] !==
|
|
1401
|
+
typeof rule[0] !== 'string' ||
|
|
1295
1402
|
!rule[0].startsWith(I.MODIFIER_PREFIX)
|
|
1296
1403
|
);
|
|
1297
1404
|
}
|