@optique/core 0.9.0-dev.211 → 0.9.0-dev.212
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constructs.cjs +1332 -602
- package/dist/constructs.d.cts +182 -62
- package/dist/constructs.d.ts +182 -62
- package/dist/constructs.js +1332 -602
- package/dist/facade.cjs +188 -144
- package/dist/facade.d.cts +41 -3
- package/dist/facade.d.ts +41 -3
- package/dist/facade.js +187 -145
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/modifiers.cjs +228 -79
- package/dist/modifiers.d.cts +11 -6
- package/dist/modifiers.d.ts +11 -6
- package/dist/modifiers.js +228 -79
- package/dist/parser.cjs +217 -33
- package/dist/parser.d.cts +202 -18
- package/dist/parser.d.ts +202 -18
- package/dist/parser.js +212 -34
- package/dist/primitives.cjs +242 -97
- package/dist/primitives.d.cts +14 -10
- package/dist/primitives.d.ts +14 -10
- package/dist/primitives.js +242 -97
- package/dist/valueparser.cjs +10 -1
- package/dist/valueparser.d.cts +29 -16
- package/dist/valueparser.d.ts +29 -16
- package/dist/valueparser.js +10 -1
- package/package.json +1 -1
package/dist/constructs.js
CHANGED
|
@@ -117,45 +117,79 @@ function generateNoMatchError(context) {
|
|
|
117
117
|
* Creates a complete() method shared by or() and longestMatch().
|
|
118
118
|
* @internal
|
|
119
119
|
*/
|
|
120
|
-
function createExclusiveComplete(parsers, options, noMatchContext) {
|
|
120
|
+
function createExclusiveComplete(parsers, options, noMatchContext, isAsync) {
|
|
121
|
+
const syncParsers = parsers;
|
|
121
122
|
return (state) => {
|
|
122
123
|
if (state == null) return {
|
|
123
124
|
success: false,
|
|
124
125
|
error: getNoMatchError(options, noMatchContext)
|
|
125
126
|
};
|
|
126
127
|
const [i, result] = state;
|
|
127
|
-
if (result.success) return
|
|
128
|
-
return {
|
|
128
|
+
if (!result.success) return {
|
|
129
129
|
success: false,
|
|
130
130
|
error: result.error
|
|
131
131
|
};
|
|
132
|
+
if (isAsync) return (async () => {
|
|
133
|
+
const completeResult = await parsers[i].complete(result.next.state);
|
|
134
|
+
return completeResult;
|
|
135
|
+
})();
|
|
136
|
+
return syncParsers[i].complete(result.next.state);
|
|
132
137
|
};
|
|
133
138
|
}
|
|
134
139
|
/**
|
|
135
140
|
* Creates a suggest() method shared by or() and longestMatch().
|
|
136
141
|
* @internal
|
|
137
142
|
*/
|
|
138
|
-
function createExclusiveSuggest(parsers) {
|
|
143
|
+
function createExclusiveSuggest(parsers, isAsync) {
|
|
144
|
+
const syncParsers = parsers;
|
|
145
|
+
if (isAsync) return (context, prefix) => {
|
|
146
|
+
return async function* () {
|
|
147
|
+
const suggestions = [];
|
|
148
|
+
if (context.state == null) for (const parser of parsers) {
|
|
149
|
+
const parserSuggestions = parser.suggest({
|
|
150
|
+
...context,
|
|
151
|
+
state: parser.initialState
|
|
152
|
+
}, prefix);
|
|
153
|
+
if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
|
|
154
|
+
else suggestions.push(...parserSuggestions);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const [index, parserResult] = context.state;
|
|
158
|
+
if (parserResult.success) {
|
|
159
|
+
const parser = parsers[index];
|
|
160
|
+
const parserSuggestions = parser.suggest({
|
|
161
|
+
...context,
|
|
162
|
+
state: parserResult.next.state
|
|
163
|
+
}, prefix);
|
|
164
|
+
if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
|
|
165
|
+
else suggestions.push(...parserSuggestions);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
yield* deduplicateSuggestions(suggestions);
|
|
169
|
+
}();
|
|
170
|
+
};
|
|
139
171
|
return (context, prefix) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
state: parser.initialState
|
|
145
|
-
}, prefix);
|
|
146
|
-
suggestions.push(...parserSuggestions);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
const [index, parserResult] = context.state;
|
|
150
|
-
if (parserResult.success) {
|
|
151
|
-
const parserSuggestions = parsers[index].suggest({
|
|
172
|
+
return function* () {
|
|
173
|
+
const suggestions = [];
|
|
174
|
+
if (context.state == null) for (const parser of syncParsers) {
|
|
175
|
+
const parserSuggestions = parser.suggest({
|
|
152
176
|
...context,
|
|
153
|
-
state:
|
|
177
|
+
state: parser.initialState
|
|
154
178
|
}, prefix);
|
|
155
179
|
suggestions.push(...parserSuggestions);
|
|
156
180
|
}
|
|
157
|
-
|
|
158
|
-
|
|
181
|
+
else {
|
|
182
|
+
const [index, parserResult] = context.state;
|
|
183
|
+
if (parserResult.success) {
|
|
184
|
+
const parserSuggestions = syncParsers[index].suggest({
|
|
185
|
+
...context,
|
|
186
|
+
state: parserResult.next.state
|
|
187
|
+
}, prefix);
|
|
188
|
+
suggestions.push(...parserSuggestions);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
yield* deduplicateSuggestions(suggestions);
|
|
192
|
+
}();
|
|
159
193
|
};
|
|
160
194
|
}
|
|
161
195
|
/**
|
|
@@ -191,7 +225,80 @@ function or(...args) {
|
|
|
191
225
|
options = void 0;
|
|
192
226
|
}
|
|
193
227
|
const noMatchContext = analyzeNoMatchContext(parsers);
|
|
228
|
+
const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
229
|
+
const isAsync = combinedMode === "async";
|
|
230
|
+
const syncParsers = parsers;
|
|
231
|
+
const getInitialError = (context) => ({
|
|
232
|
+
consumed: 0,
|
|
233
|
+
error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
|
|
234
|
+
});
|
|
235
|
+
const parseSync = (context) => {
|
|
236
|
+
let error = getInitialError(context);
|
|
237
|
+
const orderedParsers = syncParsers.map((p, i) => [p, i]);
|
|
238
|
+
orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
|
|
239
|
+
for (const [parser, i] of orderedParsers) {
|
|
240
|
+
const result = parser.parse({
|
|
241
|
+
...context,
|
|
242
|
+
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
243
|
+
});
|
|
244
|
+
if (result.success && result.consumed.length > 0) {
|
|
245
|
+
if (context.state?.[0] !== i && context.state?.[1].success) return {
|
|
246
|
+
success: false,
|
|
247
|
+
consumed: context.buffer.length - result.next.buffer.length,
|
|
248
|
+
error: message`${values(context.state[1].consumed)} and ${values(result.consumed)} cannot be used together.`
|
|
249
|
+
};
|
|
250
|
+
return {
|
|
251
|
+
success: true,
|
|
252
|
+
next: {
|
|
253
|
+
...context,
|
|
254
|
+
buffer: result.next.buffer,
|
|
255
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
256
|
+
state: [i, result]
|
|
257
|
+
},
|
|
258
|
+
consumed: result.consumed
|
|
259
|
+
};
|
|
260
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
...error,
|
|
264
|
+
success: false
|
|
265
|
+
};
|
|
266
|
+
};
|
|
267
|
+
const parseAsync = async (context) => {
|
|
268
|
+
let error = getInitialError(context);
|
|
269
|
+
const orderedParsers = parsers.map((p, i) => [p, i]);
|
|
270
|
+
orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
|
|
271
|
+
for (const [parser, i] of orderedParsers) {
|
|
272
|
+
const resultOrPromise = parser.parse({
|
|
273
|
+
...context,
|
|
274
|
+
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
275
|
+
});
|
|
276
|
+
const result = await resultOrPromise;
|
|
277
|
+
if (result.success && result.consumed.length > 0) {
|
|
278
|
+
if (context.state?.[0] !== i && context.state?.[1].success) return {
|
|
279
|
+
success: false,
|
|
280
|
+
consumed: context.buffer.length - result.next.buffer.length,
|
|
281
|
+
error: message`${values(context.state[1].consumed)} and ${values(result.consumed)} cannot be used together.`
|
|
282
|
+
};
|
|
283
|
+
return {
|
|
284
|
+
success: true,
|
|
285
|
+
next: {
|
|
286
|
+
...context,
|
|
287
|
+
buffer: result.next.buffer,
|
|
288
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
289
|
+
state: [i, result]
|
|
290
|
+
},
|
|
291
|
+
consumed: result.consumed
|
|
292
|
+
};
|
|
293
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
...error,
|
|
297
|
+
success: false
|
|
298
|
+
};
|
|
299
|
+
};
|
|
194
300
|
return {
|
|
301
|
+
$mode: combinedMode,
|
|
195
302
|
$valueType: [],
|
|
196
303
|
$stateType: [],
|
|
197
304
|
priority: Math.max(...parsers.map((p) => p.priority)),
|
|
@@ -200,43 +307,12 @@ function or(...args) {
|
|
|
200
307
|
terms: parsers.map((p) => p.usage)
|
|
201
308
|
}],
|
|
202
309
|
initialState: void 0,
|
|
203
|
-
complete: createExclusiveComplete(parsers, options, noMatchContext),
|
|
310
|
+
complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
|
|
204
311
|
parse(context) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
|
|
208
|
-
};
|
|
209
|
-
const orderedParsers = parsers.map((p, i) => [p, i]);
|
|
210
|
-
orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
|
|
211
|
-
for (const [parser, i] of orderedParsers) {
|
|
212
|
-
const result = parser.parse({
|
|
213
|
-
...context,
|
|
214
|
-
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
215
|
-
});
|
|
216
|
-
if (result.success && result.consumed.length > 0) {
|
|
217
|
-
if (context.state?.[0] !== i && context.state?.[1].success) return {
|
|
218
|
-
success: false,
|
|
219
|
-
consumed: context.buffer.length - result.next.buffer.length,
|
|
220
|
-
error: message`${values(context.state[1].consumed)} and ${values(result.consumed)} cannot be used together.`
|
|
221
|
-
};
|
|
222
|
-
return {
|
|
223
|
-
success: true,
|
|
224
|
-
next: {
|
|
225
|
-
...context,
|
|
226
|
-
buffer: result.next.buffer,
|
|
227
|
-
optionsTerminated: result.next.optionsTerminated,
|
|
228
|
-
state: [i, result]
|
|
229
|
-
},
|
|
230
|
-
consumed: result.consumed
|
|
231
|
-
};
|
|
232
|
-
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
233
|
-
}
|
|
234
|
-
return {
|
|
235
|
-
...error,
|
|
236
|
-
success: false
|
|
237
|
-
};
|
|
312
|
+
if (isAsync) return parseAsync(context);
|
|
313
|
+
return parseSync(context);
|
|
238
314
|
},
|
|
239
|
-
suggest: createExclusiveSuggest(parsers),
|
|
315
|
+
suggest: createExclusiveSuggest(parsers, isAsync),
|
|
240
316
|
getDocFragments(state, _defaultValue) {
|
|
241
317
|
let description;
|
|
242
318
|
let fragments;
|
|
@@ -285,7 +361,82 @@ function longestMatch(...args) {
|
|
|
285
361
|
options = void 0;
|
|
286
362
|
}
|
|
287
363
|
const noMatchContext = analyzeNoMatchContext(parsers);
|
|
364
|
+
const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
365
|
+
const isAsync = combinedMode === "async";
|
|
366
|
+
const syncParsers = parsers;
|
|
367
|
+
const getInitialError = (context) => ({
|
|
368
|
+
consumed: 0,
|
|
369
|
+
error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
|
|
370
|
+
});
|
|
371
|
+
const parseSync = (context) => {
|
|
372
|
+
let bestMatch = null;
|
|
373
|
+
let error = getInitialError(context);
|
|
374
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
375
|
+
const parser = syncParsers[i];
|
|
376
|
+
const result = parser.parse({
|
|
377
|
+
...context,
|
|
378
|
+
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
379
|
+
});
|
|
380
|
+
if (result.success) {
|
|
381
|
+
const consumed = context.buffer.length - result.next.buffer.length;
|
|
382
|
+
if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
|
|
383
|
+
index: i,
|
|
384
|
+
result,
|
|
385
|
+
consumed
|
|
386
|
+
};
|
|
387
|
+
} else if (error.consumed < result.consumed) error = result;
|
|
388
|
+
}
|
|
389
|
+
if (bestMatch && bestMatch.result.success) return {
|
|
390
|
+
success: true,
|
|
391
|
+
next: {
|
|
392
|
+
...context,
|
|
393
|
+
buffer: bestMatch.result.next.buffer,
|
|
394
|
+
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
395
|
+
state: [bestMatch.index, bestMatch.result]
|
|
396
|
+
},
|
|
397
|
+
consumed: bestMatch.result.consumed
|
|
398
|
+
};
|
|
399
|
+
return {
|
|
400
|
+
...error,
|
|
401
|
+
success: false
|
|
402
|
+
};
|
|
403
|
+
};
|
|
404
|
+
const parseAsync = async (context) => {
|
|
405
|
+
let bestMatch = null;
|
|
406
|
+
let error = getInitialError(context);
|
|
407
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
408
|
+
const parser = parsers[i];
|
|
409
|
+
const resultOrPromise = parser.parse({
|
|
410
|
+
...context,
|
|
411
|
+
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
412
|
+
});
|
|
413
|
+
const result = await resultOrPromise;
|
|
414
|
+
if (result.success) {
|
|
415
|
+
const consumed = context.buffer.length - result.next.buffer.length;
|
|
416
|
+
if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
|
|
417
|
+
index: i,
|
|
418
|
+
result,
|
|
419
|
+
consumed
|
|
420
|
+
};
|
|
421
|
+
} else if (error.consumed < result.consumed) error = result;
|
|
422
|
+
}
|
|
423
|
+
if (bestMatch && bestMatch.result.success) return {
|
|
424
|
+
success: true,
|
|
425
|
+
next: {
|
|
426
|
+
...context,
|
|
427
|
+
buffer: bestMatch.result.next.buffer,
|
|
428
|
+
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
429
|
+
state: [bestMatch.index, bestMatch.result]
|
|
430
|
+
},
|
|
431
|
+
consumed: bestMatch.result.consumed
|
|
432
|
+
};
|
|
433
|
+
return {
|
|
434
|
+
...error,
|
|
435
|
+
success: false
|
|
436
|
+
};
|
|
437
|
+
};
|
|
288
438
|
return {
|
|
439
|
+
$mode: combinedMode,
|
|
289
440
|
$valueType: [],
|
|
290
441
|
$stateType: [],
|
|
291
442
|
priority: Math.max(...parsers.map((p) => p.priority)),
|
|
@@ -294,44 +445,12 @@ function longestMatch(...args) {
|
|
|
294
445
|
terms: parsers.map((p) => p.usage)
|
|
295
446
|
}],
|
|
296
447
|
initialState: void 0,
|
|
297
|
-
complete: createExclusiveComplete(parsers, options, noMatchContext),
|
|
448
|
+
complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
|
|
298
449
|
parse(context) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
consumed: 0,
|
|
302
|
-
error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
|
|
303
|
-
};
|
|
304
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
305
|
-
const parser = parsers[i];
|
|
306
|
-
const result = parser.parse({
|
|
307
|
-
...context,
|
|
308
|
-
state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
|
|
309
|
-
});
|
|
310
|
-
if (result.success) {
|
|
311
|
-
const consumed = context.buffer.length - result.next.buffer.length;
|
|
312
|
-
if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
|
|
313
|
-
index: i,
|
|
314
|
-
result,
|
|
315
|
-
consumed
|
|
316
|
-
};
|
|
317
|
-
} else if (error.consumed < result.consumed) error = result;
|
|
318
|
-
}
|
|
319
|
-
if (bestMatch && bestMatch.result.success) return {
|
|
320
|
-
success: true,
|
|
321
|
-
next: {
|
|
322
|
-
...context,
|
|
323
|
-
buffer: bestMatch.result.next.buffer,
|
|
324
|
-
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
325
|
-
state: [bestMatch.index, bestMatch.result]
|
|
326
|
-
},
|
|
327
|
-
consumed: bestMatch.result.consumed
|
|
328
|
-
};
|
|
329
|
-
return {
|
|
330
|
-
...error,
|
|
331
|
-
success: false
|
|
332
|
-
};
|
|
450
|
+
if (isAsync) return parseAsync(context);
|
|
451
|
+
return parseSync(context);
|
|
333
452
|
},
|
|
334
|
-
suggest: createExclusiveSuggest(parsers),
|
|
453
|
+
suggest: createExclusiveSuggest(parsers, isAsync),
|
|
335
454
|
getDocFragments(state, _defaultValue) {
|
|
336
455
|
let description;
|
|
337
456
|
let footer;
|
|
@@ -357,6 +476,61 @@ function longestMatch(...args) {
|
|
|
357
476
|
}
|
|
358
477
|
};
|
|
359
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Internal sync helper for object suggest functionality.
|
|
481
|
+
* @internal
|
|
482
|
+
*/
|
|
483
|
+
function* suggestObjectSync(context, prefix, parserPairs) {
|
|
484
|
+
if (context.buffer.length > 0) {
|
|
485
|
+
const lastToken = context.buffer[context.buffer.length - 1];
|
|
486
|
+
for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
|
|
487
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
488
|
+
yield* parser.suggest({
|
|
489
|
+
...context,
|
|
490
|
+
state: fieldState
|
|
491
|
+
}, prefix);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
const suggestions = [];
|
|
496
|
+
for (const [field, parser] of parserPairs) {
|
|
497
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
498
|
+
const fieldSuggestions = parser.suggest({
|
|
499
|
+
...context,
|
|
500
|
+
state: fieldState
|
|
501
|
+
}, prefix);
|
|
502
|
+
suggestions.push(...fieldSuggestions);
|
|
503
|
+
}
|
|
504
|
+
yield* deduplicateSuggestions(suggestions);
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Internal async helper for object suggest functionality.
|
|
508
|
+
* @internal
|
|
509
|
+
*/
|
|
510
|
+
async function* suggestObjectAsync(context, prefix, parserPairs) {
|
|
511
|
+
if (context.buffer.length > 0) {
|
|
512
|
+
const lastToken = context.buffer[context.buffer.length - 1];
|
|
513
|
+
for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
|
|
514
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
515
|
+
const suggestions$1 = parser.suggest({
|
|
516
|
+
...context,
|
|
517
|
+
state: fieldState
|
|
518
|
+
}, prefix);
|
|
519
|
+
for await (const s of suggestions$1) yield s;
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
const suggestions = [];
|
|
524
|
+
for (const [field, parser] of parserPairs) {
|
|
525
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
526
|
+
const fieldSuggestions = parser.suggest({
|
|
527
|
+
...context,
|
|
528
|
+
state: fieldState
|
|
529
|
+
}, prefix);
|
|
530
|
+
for await (const s of fieldSuggestions) suggestions.push(s);
|
|
531
|
+
}
|
|
532
|
+
yield* deduplicateSuggestions(suggestions);
|
|
533
|
+
}
|
|
360
534
|
function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
361
535
|
const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
|
|
362
536
|
let parsers;
|
|
@@ -375,131 +549,181 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
375
549
|
for (const key of parserKeys) initialState[key] = parsers[key].initialState;
|
|
376
550
|
if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
|
|
377
551
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
552
|
+
const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
|
|
553
|
+
const isAsync = combinedMode === "async";
|
|
554
|
+
const getInitialError = (context) => ({
|
|
555
|
+
consumed: 0,
|
|
556
|
+
error: context.buffer.length > 0 ? (() => {
|
|
557
|
+
const token = context.buffer[0];
|
|
558
|
+
const customMessage = options.errors?.unexpectedInput;
|
|
559
|
+
if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
|
|
560
|
+
const baseError = message`Unexpected option or argument: ${token}.`;
|
|
561
|
+
return createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
|
|
562
|
+
})() : (() => {
|
|
563
|
+
const customEndOfInput = options.errors?.endOfInput;
|
|
564
|
+
return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
|
|
565
|
+
})()
|
|
566
|
+
});
|
|
567
|
+
const parseSync = (context) => {
|
|
568
|
+
let error = getInitialError(context);
|
|
569
|
+
let currentContext = context;
|
|
570
|
+
let anySuccess = false;
|
|
571
|
+
const allConsumed = [];
|
|
572
|
+
let madeProgress = true;
|
|
573
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
574
|
+
madeProgress = false;
|
|
575
|
+
for (const [field, parser] of parserPairs) {
|
|
576
|
+
const result = parser.parse({
|
|
577
|
+
...currentContext,
|
|
578
|
+
state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
|
|
579
|
+
});
|
|
580
|
+
if (result.success && result.consumed.length > 0) {
|
|
581
|
+
currentContext = {
|
|
582
|
+
...currentContext,
|
|
583
|
+
buffer: result.next.buffer,
|
|
584
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
585
|
+
state: {
|
|
586
|
+
...currentContext.state,
|
|
587
|
+
[field]: result.next.state
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
allConsumed.push(...result.consumed);
|
|
591
|
+
anySuccess = true;
|
|
592
|
+
madeProgress = true;
|
|
593
|
+
break;
|
|
594
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (anySuccess) return {
|
|
598
|
+
success: true,
|
|
599
|
+
next: currentContext,
|
|
600
|
+
consumed: allConsumed
|
|
601
|
+
};
|
|
602
|
+
if (context.buffer.length === 0) {
|
|
603
|
+
let allCanComplete = true;
|
|
604
|
+
for (const [field, parser] of parserPairs) {
|
|
605
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
606
|
+
const completeResult = parser.complete(fieldState);
|
|
607
|
+
if (!completeResult.success) {
|
|
608
|
+
allCanComplete = false;
|
|
609
|
+
break;
|
|
393
610
|
}
|
|
394
|
-
for (const [name, sources] of optionNameSources) if (sources.length > 1) return {
|
|
395
|
-
success: false,
|
|
396
|
-
consumed: 0,
|
|
397
|
-
error: message`Duplicate option name ${optionName(name)} found in fields: ${values(sources.map((s) => typeof s === "symbol" ? s.description ?? s.toString() : s))}. Each option name must be unique within a parser combinator.`
|
|
398
|
-
};
|
|
399
611
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const customMessage = options.errors?.unexpectedInput;
|
|
405
|
-
if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
|
|
406
|
-
const baseError = message`Unexpected option or argument: ${token}.`;
|
|
407
|
-
return createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
|
|
408
|
-
})() : (() => {
|
|
409
|
-
const customEndOfInput = options.errors?.endOfInput;
|
|
410
|
-
return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
|
|
411
|
-
})()
|
|
612
|
+
if (allCanComplete) return {
|
|
613
|
+
success: true,
|
|
614
|
+
next: context,
|
|
615
|
+
consumed: []
|
|
412
616
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
...error,
|
|
620
|
+
success: false
|
|
621
|
+
};
|
|
622
|
+
};
|
|
623
|
+
const parseAsync = async (context) => {
|
|
624
|
+
let error = getInitialError(context);
|
|
625
|
+
let currentContext = context;
|
|
626
|
+
let anySuccess = false;
|
|
627
|
+
const allConsumed = [];
|
|
628
|
+
let madeProgress = true;
|
|
629
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
630
|
+
madeProgress = false;
|
|
631
|
+
for (const [field, parser] of parserPairs) {
|
|
632
|
+
const resultOrPromise = parser.parse({
|
|
633
|
+
...currentContext,
|
|
634
|
+
state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
|
|
635
|
+
});
|
|
636
|
+
const result = await resultOrPromise;
|
|
637
|
+
if (result.success && result.consumed.length > 0) {
|
|
638
|
+
currentContext = {
|
|
421
639
|
...currentContext,
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
640
|
+
buffer: result.next.buffer,
|
|
641
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
642
|
+
state: {
|
|
643
|
+
...currentContext.state,
|
|
644
|
+
[field]: result.next.state
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
allConsumed.push(...result.consumed);
|
|
648
|
+
anySuccess = true;
|
|
649
|
+
madeProgress = true;
|
|
650
|
+
break;
|
|
651
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
if (anySuccess) return {
|
|
655
|
+
success: true,
|
|
656
|
+
next: currentContext,
|
|
657
|
+
consumed: allConsumed
|
|
658
|
+
};
|
|
659
|
+
if (context.buffer.length === 0) {
|
|
660
|
+
let allCanComplete = true;
|
|
661
|
+
for (const [field, parser] of parserPairs) {
|
|
662
|
+
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
663
|
+
const completeResult = await parser.complete(fieldState);
|
|
664
|
+
if (!completeResult.success) {
|
|
665
|
+
allCanComplete = false;
|
|
666
|
+
break;
|
|
439
667
|
}
|
|
440
668
|
}
|
|
441
|
-
if (
|
|
669
|
+
if (allCanComplete) return {
|
|
442
670
|
success: true,
|
|
443
|
-
next:
|
|
444
|
-
consumed:
|
|
671
|
+
next: context,
|
|
672
|
+
consumed: []
|
|
445
673
|
};
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
674
|
+
}
|
|
675
|
+
return {
|
|
676
|
+
...error,
|
|
677
|
+
success: false
|
|
678
|
+
};
|
|
679
|
+
};
|
|
680
|
+
return {
|
|
681
|
+
$mode: combinedMode,
|
|
682
|
+
$valueType: [],
|
|
683
|
+
$stateType: [],
|
|
684
|
+
priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
|
|
685
|
+
usage: parserPairs.flatMap(([_, p]) => p.usage),
|
|
686
|
+
initialState,
|
|
687
|
+
parse(context) {
|
|
688
|
+
if (isAsync) return parseAsync(context);
|
|
689
|
+
return parseSync(context);
|
|
690
|
+
},
|
|
691
|
+
complete(state) {
|
|
692
|
+
if (!isAsync) {
|
|
693
|
+
const result = {};
|
|
694
|
+
for (const field of parserKeys) {
|
|
695
|
+
const valueResult = parsers[field].complete(state[field]);
|
|
696
|
+
if (valueResult.success) result[field] = valueResult.value;
|
|
697
|
+
else return {
|
|
698
|
+
success: false,
|
|
699
|
+
error: valueResult.error
|
|
700
|
+
};
|
|
455
701
|
}
|
|
456
|
-
|
|
702
|
+
return {
|
|
457
703
|
success: true,
|
|
458
|
-
|
|
459
|
-
consumed: []
|
|
704
|
+
value: result
|
|
460
705
|
};
|
|
461
706
|
}
|
|
462
|
-
return {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
success:
|
|
474
|
-
|
|
707
|
+
return (async () => {
|
|
708
|
+
const result = {};
|
|
709
|
+
for (const field of parserKeys) {
|
|
710
|
+
const valueResult = await parsers[field].complete(state[field]);
|
|
711
|
+
if (valueResult.success) result[field] = valueResult.value;
|
|
712
|
+
else return {
|
|
713
|
+
success: false,
|
|
714
|
+
error: valueResult.error
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
return {
|
|
718
|
+
success: true,
|
|
719
|
+
value: result
|
|
475
720
|
};
|
|
476
|
-
}
|
|
477
|
-
return {
|
|
478
|
-
success: true,
|
|
479
|
-
value: result
|
|
480
|
-
};
|
|
721
|
+
})();
|
|
481
722
|
},
|
|
482
723
|
suggest(context, prefix) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
|
|
487
|
-
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
488
|
-
return Array.from(parser.suggest({
|
|
489
|
-
...context,
|
|
490
|
-
state: fieldState
|
|
491
|
-
}, prefix));
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
for (const [field, parser] of parserPairs) {
|
|
495
|
-
const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
|
|
496
|
-
const fieldSuggestions = parser.suggest({
|
|
497
|
-
...context,
|
|
498
|
-
state: fieldState
|
|
499
|
-
}, prefix);
|
|
500
|
-
suggestions.push(...fieldSuggestions);
|
|
501
|
-
}
|
|
502
|
-
return deduplicateSuggestions(suggestions);
|
|
724
|
+
if (isAsync) return suggestObjectAsync(context, prefix, parserPairs);
|
|
725
|
+
const syncParserPairs = parserPairs;
|
|
726
|
+
return suggestObjectSync(context, prefix, syncParserPairs);
|
|
503
727
|
},
|
|
504
728
|
getDocFragments(state, defaultValue) {
|
|
505
729
|
const fragments = parserPairs.flatMap(([field, p]) => {
|
|
@@ -528,6 +752,35 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
528
752
|
}
|
|
529
753
|
};
|
|
530
754
|
}
|
|
755
|
+
function suggestTupleSync(context, prefix, parsers) {
|
|
756
|
+
const suggestions = [];
|
|
757
|
+
const stateArray = context.state;
|
|
758
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
759
|
+
const parser = parsers[i];
|
|
760
|
+
const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
|
|
761
|
+
const parserSuggestions = parser.suggest({
|
|
762
|
+
...context,
|
|
763
|
+
state: parserState
|
|
764
|
+
}, prefix);
|
|
765
|
+
suggestions.push(...parserSuggestions);
|
|
766
|
+
}
|
|
767
|
+
return deduplicateSuggestions(suggestions);
|
|
768
|
+
}
|
|
769
|
+
async function* suggestTupleAsync(context, prefix, parsers) {
|
|
770
|
+
const suggestions = [];
|
|
771
|
+
const stateArray = context.state;
|
|
772
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
773
|
+
const parser = parsers[i];
|
|
774
|
+
const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
|
|
775
|
+
const parserSuggestions = parser.suggest({
|
|
776
|
+
...context,
|
|
777
|
+
state: parserState
|
|
778
|
+
}, prefix);
|
|
779
|
+
if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
|
|
780
|
+
else suggestions.push(...parserSuggestions);
|
|
781
|
+
}
|
|
782
|
+
yield* deduplicateSuggestions(suggestions);
|
|
783
|
+
}
|
|
531
784
|
function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
532
785
|
const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
|
|
533
786
|
let parsers;
|
|
@@ -539,102 +792,187 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
539
792
|
parsers = labelOrParsers;
|
|
540
793
|
options = maybeParsersOrOptions ?? {};
|
|
541
794
|
}
|
|
795
|
+
const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
796
|
+
const isAsync = combinedMode === "async";
|
|
797
|
+
const syncParsers = parsers;
|
|
542
798
|
if (!options.allowDuplicates) checkDuplicateOptionNames(parsers.map((parser, index) => [String(index), parser.usage]));
|
|
799
|
+
const parseSync = (context) => {
|
|
800
|
+
let currentContext = context;
|
|
801
|
+
const allConsumed = [];
|
|
802
|
+
const matchedParsers = /* @__PURE__ */ new Set();
|
|
803
|
+
while (matchedParsers.size < syncParsers.length) {
|
|
804
|
+
let foundMatch = false;
|
|
805
|
+
let error = {
|
|
806
|
+
consumed: 0,
|
|
807
|
+
error: message`No remaining parsers could match the input.`
|
|
808
|
+
};
|
|
809
|
+
const stateArray = currentContext.state;
|
|
810
|
+
const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
811
|
+
for (const [parser, index] of remainingParsers) {
|
|
812
|
+
const result = parser.parse({
|
|
813
|
+
...currentContext,
|
|
814
|
+
state: stateArray[index]
|
|
815
|
+
});
|
|
816
|
+
if (result.success && result.consumed.length > 0) {
|
|
817
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
818
|
+
currentContext = {
|
|
819
|
+
...currentContext,
|
|
820
|
+
buffer: result.next.buffer,
|
|
821
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
822
|
+
state: newStateArray
|
|
823
|
+
};
|
|
824
|
+
allConsumed.push(...result.consumed);
|
|
825
|
+
matchedParsers.add(index);
|
|
826
|
+
foundMatch = true;
|
|
827
|
+
break;
|
|
828
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
829
|
+
}
|
|
830
|
+
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
831
|
+
const result = parser.parse({
|
|
832
|
+
...currentContext,
|
|
833
|
+
state: stateArray[index]
|
|
834
|
+
});
|
|
835
|
+
if (result.success && result.consumed.length < 1) {
|
|
836
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
837
|
+
currentContext = {
|
|
838
|
+
...currentContext,
|
|
839
|
+
state: newStateArray
|
|
840
|
+
};
|
|
841
|
+
matchedParsers.add(index);
|
|
842
|
+
foundMatch = true;
|
|
843
|
+
break;
|
|
844
|
+
} else if (!result.success && result.consumed < 1) {
|
|
845
|
+
matchedParsers.add(index);
|
|
846
|
+
foundMatch = true;
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
if (!foundMatch) return {
|
|
851
|
+
...error,
|
|
852
|
+
success: false
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
return {
|
|
856
|
+
success: true,
|
|
857
|
+
next: currentContext,
|
|
858
|
+
consumed: allConsumed
|
|
859
|
+
};
|
|
860
|
+
};
|
|
861
|
+
const parseAsync = async (context) => {
|
|
862
|
+
let currentContext = context;
|
|
863
|
+
const allConsumed = [];
|
|
864
|
+
const matchedParsers = /* @__PURE__ */ new Set();
|
|
865
|
+
while (matchedParsers.size < parsers.length) {
|
|
866
|
+
let foundMatch = false;
|
|
867
|
+
let error = {
|
|
868
|
+
consumed: 0,
|
|
869
|
+
error: message`No remaining parsers could match the input.`
|
|
870
|
+
};
|
|
871
|
+
const stateArray = currentContext.state;
|
|
872
|
+
const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
873
|
+
for (const [parser, index] of remainingParsers) {
|
|
874
|
+
const resultOrPromise = parser.parse({
|
|
875
|
+
...currentContext,
|
|
876
|
+
state: stateArray[index]
|
|
877
|
+
});
|
|
878
|
+
const result = await resultOrPromise;
|
|
879
|
+
if (result.success && result.consumed.length > 0) {
|
|
880
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
881
|
+
currentContext = {
|
|
882
|
+
...currentContext,
|
|
883
|
+
buffer: result.next.buffer,
|
|
884
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
885
|
+
state: newStateArray
|
|
886
|
+
};
|
|
887
|
+
allConsumed.push(...result.consumed);
|
|
888
|
+
matchedParsers.add(index);
|
|
889
|
+
foundMatch = true;
|
|
890
|
+
break;
|
|
891
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
892
|
+
}
|
|
893
|
+
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
894
|
+
const resultOrPromise = parser.parse({
|
|
895
|
+
...currentContext,
|
|
896
|
+
state: stateArray[index]
|
|
897
|
+
});
|
|
898
|
+
const result = await resultOrPromise;
|
|
899
|
+
if (result.success && result.consumed.length < 1) {
|
|
900
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
901
|
+
currentContext = {
|
|
902
|
+
...currentContext,
|
|
903
|
+
state: newStateArray
|
|
904
|
+
};
|
|
905
|
+
matchedParsers.add(index);
|
|
906
|
+
foundMatch = true;
|
|
907
|
+
break;
|
|
908
|
+
} else if (!result.success && result.consumed < 1) {
|
|
909
|
+
matchedParsers.add(index);
|
|
910
|
+
foundMatch = true;
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
if (!foundMatch) return {
|
|
915
|
+
...error,
|
|
916
|
+
success: false
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
return {
|
|
920
|
+
success: true,
|
|
921
|
+
next: currentContext,
|
|
922
|
+
consumed: allConsumed
|
|
923
|
+
};
|
|
924
|
+
};
|
|
543
925
|
return {
|
|
926
|
+
$mode: combinedMode,
|
|
544
927
|
$valueType: [],
|
|
545
928
|
$stateType: [],
|
|
546
929
|
usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
|
|
547
930
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
548
931
|
initialState: parsers.map((parser) => parser.initialState),
|
|
549
932
|
parse(context) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const matchedParsers = /* @__PURE__ */ new Set();
|
|
553
|
-
while (matchedParsers.size < parsers.length) {
|
|
554
|
-
let foundMatch = false;
|
|
555
|
-
let error = {
|
|
556
|
-
consumed: 0,
|
|
557
|
-
error: message`No remaining parsers could match the input.`
|
|
558
|
-
};
|
|
559
|
-
const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
560
|
-
for (const [parser, index] of remainingParsers) {
|
|
561
|
-
const result = parser.parse({
|
|
562
|
-
...currentContext,
|
|
563
|
-
state: currentContext.state[index]
|
|
564
|
-
});
|
|
565
|
-
if (result.success && result.consumed.length > 0) {
|
|
566
|
-
currentContext = {
|
|
567
|
-
...currentContext,
|
|
568
|
-
buffer: result.next.buffer,
|
|
569
|
-
optionsTerminated: result.next.optionsTerminated,
|
|
570
|
-
state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
|
|
571
|
-
};
|
|
572
|
-
allConsumed.push(...result.consumed);
|
|
573
|
-
matchedParsers.add(index);
|
|
574
|
-
foundMatch = true;
|
|
575
|
-
break;
|
|
576
|
-
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
577
|
-
}
|
|
578
|
-
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
579
|
-
const result = parser.parse({
|
|
580
|
-
...currentContext,
|
|
581
|
-
state: currentContext.state[index]
|
|
582
|
-
});
|
|
583
|
-
if (result.success && result.consumed.length < 1) {
|
|
584
|
-
currentContext = {
|
|
585
|
-
...currentContext,
|
|
586
|
-
state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
|
|
587
|
-
};
|
|
588
|
-
matchedParsers.add(index);
|
|
589
|
-
foundMatch = true;
|
|
590
|
-
break;
|
|
591
|
-
} else if (!result.success && result.consumed < 1) {
|
|
592
|
-
matchedParsers.add(index);
|
|
593
|
-
foundMatch = true;
|
|
594
|
-
break;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
if (!foundMatch) return {
|
|
598
|
-
...error,
|
|
599
|
-
success: false
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
return {
|
|
603
|
-
success: true,
|
|
604
|
-
next: currentContext,
|
|
605
|
-
consumed: allConsumed
|
|
606
|
-
};
|
|
933
|
+
if (isAsync) return parseAsync(context);
|
|
934
|
+
return parseSync(context);
|
|
607
935
|
},
|
|
608
936
|
complete(state) {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
success
|
|
615
|
-
|
|
937
|
+
if (!isAsync) {
|
|
938
|
+
const result = [];
|
|
939
|
+
const stateArray = state;
|
|
940
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
941
|
+
const valueResult = syncParsers[i].complete(stateArray[i]);
|
|
942
|
+
if (valueResult.success) result[i] = valueResult.value;
|
|
943
|
+
else return {
|
|
944
|
+
success: false,
|
|
945
|
+
error: valueResult.error
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
return {
|
|
949
|
+
success: true,
|
|
950
|
+
value: result
|
|
616
951
|
};
|
|
617
952
|
}
|
|
618
|
-
return {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
953
|
+
return (async () => {
|
|
954
|
+
const result = [];
|
|
955
|
+
const stateArray = state;
|
|
956
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
957
|
+
const valueResult = await parsers[i].complete(stateArray[i]);
|
|
958
|
+
if (valueResult.success) result[i] = valueResult.value;
|
|
959
|
+
else return {
|
|
960
|
+
success: false,
|
|
961
|
+
error: valueResult.error
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
success: true,
|
|
966
|
+
value: result
|
|
967
|
+
};
|
|
968
|
+
})();
|
|
622
969
|
},
|
|
623
970
|
suggest(context, prefix) {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
const parser = parsers[i];
|
|
627
|
-
const parserState = context.state && Array.isArray(context.state) ? context.state[i] : parser.initialState;
|
|
628
|
-
const parserSuggestions = parser.suggest({
|
|
629
|
-
...context,
|
|
630
|
-
state: parserState
|
|
631
|
-
}, prefix);
|
|
632
|
-
suggestions.push(...parserSuggestions);
|
|
633
|
-
}
|
|
634
|
-
return deduplicateSuggestions(suggestions);
|
|
971
|
+
if (isAsync) return suggestTupleAsync(context, prefix, parsers);
|
|
972
|
+
return suggestTupleSync(context, prefix, syncParsers);
|
|
635
973
|
},
|
|
636
974
|
getDocFragments(state, defaultValue) {
|
|
637
|
-
const fragments =
|
|
975
|
+
const fragments = syncParsers.flatMap((p, i) => {
|
|
638
976
|
const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
|
|
639
977
|
kind: "available",
|
|
640
978
|
state: state.state[i]
|
|
@@ -671,127 +1009,235 @@ function merge(...args) {
|
|
|
671
1009
|
const startIndex = typeof args[0] === "string" ? 1 : 0;
|
|
672
1010
|
const endIndex = lastArg && typeof lastArg === "object" && !("parse" in lastArg) && !("complete" in lastArg) ? args.length - 1 : args.length;
|
|
673
1011
|
const rawParsers = args.slice(startIndex, endIndex);
|
|
1012
|
+
const combinedMode = rawParsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
1013
|
+
const isAsync = combinedMode === "async";
|
|
1014
|
+
const syncRawParsers = rawParsers;
|
|
674
1015
|
const withIndex = rawParsers.map((p, i) => [p, i]);
|
|
675
1016
|
const sorted = withIndex.toSorted(([a], [b]) => b.priority - a.priority);
|
|
676
1017
|
const parsers = sorted.map(([p]) => p);
|
|
1018
|
+
const syncWithIndex = syncRawParsers.map((p, i) => [p, i]);
|
|
1019
|
+
const syncSorted = syncWithIndex.toSorted(([a], [b]) => b.priority - a.priority);
|
|
1020
|
+
const syncParsers = syncSorted.map(([p]) => p);
|
|
677
1021
|
if (!options.allowDuplicates) checkDuplicateOptionNames(sorted.map(([parser, originalIndex]) => [String(originalIndex), parser.usage]));
|
|
678
1022
|
const initialState = {};
|
|
679
1023
|
for (const parser of parsers) if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
|
|
1024
|
+
const extractParserState = (parser, context, index) => {
|
|
1025
|
+
if (parser.initialState === void 0) {
|
|
1026
|
+
const key = `__parser_${index}`;
|
|
1027
|
+
if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
|
|
1028
|
+
return void 0;
|
|
1029
|
+
} else if (parser.initialState && typeof parser.initialState === "object") {
|
|
1030
|
+
if (context.state && typeof context.state === "object") {
|
|
1031
|
+
const extractedState = {};
|
|
1032
|
+
for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
|
|
1033
|
+
return extractedState;
|
|
1034
|
+
}
|
|
1035
|
+
return parser.initialState;
|
|
1036
|
+
}
|
|
1037
|
+
return parser.initialState;
|
|
1038
|
+
};
|
|
1039
|
+
const mergeResultState = (parser, context, result, index) => {
|
|
1040
|
+
if (parser.initialState === void 0) {
|
|
1041
|
+
const key = `__parser_${index}`;
|
|
1042
|
+
if (result.success) {
|
|
1043
|
+
if (result.consumed.length > 0 || result.next.state !== void 0) return {
|
|
1044
|
+
...context.state,
|
|
1045
|
+
[key]: result.next.state
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
return { ...context.state };
|
|
1049
|
+
}
|
|
1050
|
+
return result.success ? {
|
|
1051
|
+
...context.state,
|
|
1052
|
+
...result.next.state
|
|
1053
|
+
} : { ...context.state };
|
|
1054
|
+
};
|
|
1055
|
+
const parseSync = (context) => {
|
|
1056
|
+
let currentContext = context;
|
|
1057
|
+
let zeroConsumedSuccess = null;
|
|
1058
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
1059
|
+
const parser = syncParsers[i];
|
|
1060
|
+
const parserState = extractParserState(parser, currentContext, i);
|
|
1061
|
+
const result = parser.parse({
|
|
1062
|
+
...currentContext,
|
|
1063
|
+
state: parserState
|
|
1064
|
+
});
|
|
1065
|
+
if (result.success) {
|
|
1066
|
+
const newState = mergeResultState(parser, currentContext, result, i);
|
|
1067
|
+
const newContext = {
|
|
1068
|
+
...currentContext,
|
|
1069
|
+
buffer: result.next.buffer,
|
|
1070
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1071
|
+
state: newState
|
|
1072
|
+
};
|
|
1073
|
+
if (result.consumed.length > 0) return {
|
|
1074
|
+
success: true,
|
|
1075
|
+
next: newContext,
|
|
1076
|
+
consumed: result.consumed
|
|
1077
|
+
};
|
|
1078
|
+
currentContext = newContext;
|
|
1079
|
+
if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
|
|
1080
|
+
context: newContext,
|
|
1081
|
+
consumed: []
|
|
1082
|
+
};
|
|
1083
|
+
else zeroConsumedSuccess.context = newContext;
|
|
1084
|
+
} else if (result.consumed < 1) continue;
|
|
1085
|
+
else return result;
|
|
1086
|
+
}
|
|
1087
|
+
if (zeroConsumedSuccess !== null) return {
|
|
1088
|
+
success: true,
|
|
1089
|
+
next: zeroConsumedSuccess.context,
|
|
1090
|
+
consumed: zeroConsumedSuccess.consumed
|
|
1091
|
+
};
|
|
1092
|
+
return {
|
|
1093
|
+
success: false,
|
|
1094
|
+
consumed: 0,
|
|
1095
|
+
error: message`No matching option or argument found.`
|
|
1096
|
+
};
|
|
1097
|
+
};
|
|
1098
|
+
const parseAsync = async (context) => {
|
|
1099
|
+
let currentContext = context;
|
|
1100
|
+
let zeroConsumedSuccess = null;
|
|
1101
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1102
|
+
const parser = parsers[i];
|
|
1103
|
+
const parserState = extractParserState(parser, currentContext, i);
|
|
1104
|
+
const resultOrPromise = parser.parse({
|
|
1105
|
+
...currentContext,
|
|
1106
|
+
state: parserState
|
|
1107
|
+
});
|
|
1108
|
+
const result = await resultOrPromise;
|
|
1109
|
+
if (result.success) {
|
|
1110
|
+
const newState = mergeResultState(parser, currentContext, result, i);
|
|
1111
|
+
const newContext = {
|
|
1112
|
+
...currentContext,
|
|
1113
|
+
buffer: result.next.buffer,
|
|
1114
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1115
|
+
state: newState
|
|
1116
|
+
};
|
|
1117
|
+
if (result.consumed.length > 0) return {
|
|
1118
|
+
success: true,
|
|
1119
|
+
next: newContext,
|
|
1120
|
+
consumed: result.consumed
|
|
1121
|
+
};
|
|
1122
|
+
currentContext = newContext;
|
|
1123
|
+
if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
|
|
1124
|
+
context: newContext,
|
|
1125
|
+
consumed: []
|
|
1126
|
+
};
|
|
1127
|
+
else zeroConsumedSuccess.context = newContext;
|
|
1128
|
+
} else if (result.consumed < 1) continue;
|
|
1129
|
+
else return result;
|
|
1130
|
+
}
|
|
1131
|
+
if (zeroConsumedSuccess !== null) return {
|
|
1132
|
+
success: true,
|
|
1133
|
+
next: zeroConsumedSuccess.context,
|
|
1134
|
+
consumed: zeroConsumedSuccess.consumed
|
|
1135
|
+
};
|
|
1136
|
+
return {
|
|
1137
|
+
success: false,
|
|
1138
|
+
consumed: 0,
|
|
1139
|
+
error: message`No matching option or argument found.`
|
|
1140
|
+
};
|
|
1141
|
+
};
|
|
680
1142
|
return {
|
|
1143
|
+
$mode: combinedMode,
|
|
681
1144
|
$valueType: [],
|
|
682
1145
|
$stateType: [],
|
|
683
1146
|
priority: Math.max(...parsers.map((p) => p.priority)),
|
|
684
1147
|
usage: parsers.flatMap((p) => p.usage),
|
|
685
1148
|
initialState,
|
|
686
1149
|
parse(context) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
const parser = parsers[i];
|
|
690
|
-
let parserState;
|
|
691
|
-
if (parser.initialState === void 0) {
|
|
692
|
-
const key = `__parser_${i}`;
|
|
693
|
-
if (context.state && typeof context.state === "object" && key in context.state) parserState = context.state[key];
|
|
694
|
-
else parserState = void 0;
|
|
695
|
-
} else if (parser.initialState && typeof parser.initialState === "object") if (context.state && typeof context.state === "object") {
|
|
696
|
-
const extractedState = {};
|
|
697
|
-
for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
|
|
698
|
-
parserState = extractedState;
|
|
699
|
-
} else parserState = parser.initialState;
|
|
700
|
-
else parserState = parser.initialState;
|
|
701
|
-
const result = parser.parse({
|
|
702
|
-
...context,
|
|
703
|
-
state: parserState
|
|
704
|
-
});
|
|
705
|
-
if (result.success) {
|
|
706
|
-
let newState;
|
|
707
|
-
if (parser.initialState === void 0) {
|
|
708
|
-
const key = `__parser_${i}`;
|
|
709
|
-
if (result.consumed.length > 0 || result.next.state !== void 0) newState = {
|
|
710
|
-
...context.state,
|
|
711
|
-
[key]: result.next.state
|
|
712
|
-
};
|
|
713
|
-
else newState = { ...context.state };
|
|
714
|
-
} else newState = {
|
|
715
|
-
...context.state,
|
|
716
|
-
...result.next.state
|
|
717
|
-
};
|
|
718
|
-
const newContext = {
|
|
719
|
-
...context,
|
|
720
|
-
buffer: result.next.buffer,
|
|
721
|
-
optionsTerminated: result.next.optionsTerminated,
|
|
722
|
-
state: newState
|
|
723
|
-
};
|
|
724
|
-
if (result.consumed.length > 0) return {
|
|
725
|
-
success: true,
|
|
726
|
-
next: newContext,
|
|
727
|
-
consumed: result.consumed
|
|
728
|
-
};
|
|
729
|
-
context = newContext;
|
|
730
|
-
if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
|
|
731
|
-
context: newContext,
|
|
732
|
-
consumed: []
|
|
733
|
-
};
|
|
734
|
-
else zeroConsumedSuccess.context = newContext;
|
|
735
|
-
} else if (result.consumed < 1) continue;
|
|
736
|
-
else return result;
|
|
737
|
-
}
|
|
738
|
-
if (zeroConsumedSuccess !== null) return {
|
|
739
|
-
success: true,
|
|
740
|
-
next: zeroConsumedSuccess.context,
|
|
741
|
-
consumed: zeroConsumedSuccess.consumed
|
|
742
|
-
};
|
|
743
|
-
return {
|
|
744
|
-
success: false,
|
|
745
|
-
consumed: 0,
|
|
746
|
-
error: message`No matching option or argument found.`
|
|
747
|
-
};
|
|
1150
|
+
if (isAsync) return parseAsync(context);
|
|
1151
|
+
return parseSync(context);
|
|
748
1152
|
},
|
|
749
1153
|
complete(state) {
|
|
750
|
-
const
|
|
751
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
752
|
-
const parser = parsers[i];
|
|
753
|
-
let parserState;
|
|
1154
|
+
const extractCompleteState = (parser, index) => {
|
|
754
1155
|
if (parser.initialState === void 0) {
|
|
755
|
-
const key = `__parser_${
|
|
756
|
-
if (state && typeof state === "object" && key in state)
|
|
757
|
-
|
|
758
|
-
} else if (parser.initialState && typeof parser.initialState === "object")
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
return {
|
|
769
|
-
success: true,
|
|
770
|
-
value: object$1
|
|
1156
|
+
const key = `__parser_${index}`;
|
|
1157
|
+
if (state && typeof state === "object" && key in state) return state[key];
|
|
1158
|
+
return void 0;
|
|
1159
|
+
} else if (parser.initialState && typeof parser.initialState === "object") {
|
|
1160
|
+
if (state && typeof state === "object") {
|
|
1161
|
+
const extractedState = {};
|
|
1162
|
+
for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
|
|
1163
|
+
return extractedState;
|
|
1164
|
+
}
|
|
1165
|
+
return parser.initialState;
|
|
1166
|
+
}
|
|
1167
|
+
return parser.initialState;
|
|
771
1168
|
};
|
|
1169
|
+
if (!isAsync) {
|
|
1170
|
+
const object$1 = {};
|
|
1171
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
1172
|
+
const parser = syncParsers[i];
|
|
1173
|
+
const parserState = extractCompleteState(parser, i);
|
|
1174
|
+
const result = parser.complete(parserState);
|
|
1175
|
+
if (!result.success) return result;
|
|
1176
|
+
for (const field in result.value) object$1[field] = result.value[field];
|
|
1177
|
+
}
|
|
1178
|
+
return {
|
|
1179
|
+
success: true,
|
|
1180
|
+
value: object$1
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
return (async () => {
|
|
1184
|
+
const object$1 = {};
|
|
1185
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1186
|
+
const parser = parsers[i];
|
|
1187
|
+
const parserState = extractCompleteState(parser, i);
|
|
1188
|
+
const result = await parser.complete(parserState);
|
|
1189
|
+
if (!result.success) return result;
|
|
1190
|
+
for (const field in result.value) object$1[field] = result.value[field];
|
|
1191
|
+
}
|
|
1192
|
+
return {
|
|
1193
|
+
success: true,
|
|
1194
|
+
value: object$1
|
|
1195
|
+
};
|
|
1196
|
+
})();
|
|
772
1197
|
},
|
|
773
1198
|
suggest(context, prefix) {
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
const parser = parsers[i];
|
|
777
|
-
let parserState;
|
|
778
|
-
if (parser.initialState === void 0) {
|
|
1199
|
+
const extractState = (p, i) => {
|
|
1200
|
+
if (p.initialState === void 0) {
|
|
779
1201
|
const key = `__parser_${i}`;
|
|
780
|
-
if (context.state && typeof context.state === "object" && key in context.state)
|
|
781
|
-
|
|
782
|
-
} else if (
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
1202
|
+
if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
|
|
1203
|
+
return void 0;
|
|
1204
|
+
} else if (p.initialState && typeof p.initialState === "object") {
|
|
1205
|
+
if (context.state && typeof context.state === "object") {
|
|
1206
|
+
const extractedState = {};
|
|
1207
|
+
for (const field in p.initialState) extractedState[field] = field in context.state ? context.state[field] : p.initialState[field];
|
|
1208
|
+
return extractedState;
|
|
1209
|
+
}
|
|
1210
|
+
return p.initialState;
|
|
1211
|
+
}
|
|
1212
|
+
return p.initialState;
|
|
1213
|
+
};
|
|
1214
|
+
if (isAsync) return async function* () {
|
|
1215
|
+
const suggestions = [];
|
|
1216
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1217
|
+
const parser = parsers[i];
|
|
1218
|
+
const parserState = extractState(parser, i);
|
|
1219
|
+
const parserSuggestions = parser.suggest({
|
|
1220
|
+
...context,
|
|
1221
|
+
state: parserState
|
|
1222
|
+
}, prefix);
|
|
1223
|
+
if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
|
|
1224
|
+
else suggestions.push(...parserSuggestions);
|
|
1225
|
+
}
|
|
1226
|
+
yield* deduplicateSuggestions(suggestions);
|
|
1227
|
+
}();
|
|
1228
|
+
return function* () {
|
|
1229
|
+
const suggestions = [];
|
|
1230
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
1231
|
+
const parser = syncParsers[i];
|
|
1232
|
+
const parserState = extractState(parser, i);
|
|
1233
|
+
const parserSuggestions = parser.suggest({
|
|
1234
|
+
...context,
|
|
1235
|
+
state: parserState
|
|
1236
|
+
}, prefix);
|
|
1237
|
+
suggestions.push(...parserSuggestions);
|
|
1238
|
+
}
|
|
1239
|
+
yield* deduplicateSuggestions(suggestions);
|
|
1240
|
+
}();
|
|
795
1241
|
},
|
|
796
1242
|
getDocFragments(state, _defaultValue) {
|
|
797
1243
|
const fragments = parsers.flatMap((p, i) => {
|
|
@@ -838,102 +1284,213 @@ function merge(...args) {
|
|
|
838
1284
|
};
|
|
839
1285
|
}
|
|
840
1286
|
function concat(...parsers) {
|
|
1287
|
+
const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
1288
|
+
const isAsync = combinedMode === "async";
|
|
1289
|
+
const syncParsers = parsers;
|
|
841
1290
|
const initialState = parsers.map((parser) => parser.initialState);
|
|
1291
|
+
const parseSync = (context) => {
|
|
1292
|
+
let currentContext = context;
|
|
1293
|
+
const allConsumed = [];
|
|
1294
|
+
const matchedParsers = /* @__PURE__ */ new Set();
|
|
1295
|
+
while (matchedParsers.size < syncParsers.length) {
|
|
1296
|
+
let foundMatch = false;
|
|
1297
|
+
let error = {
|
|
1298
|
+
consumed: 0,
|
|
1299
|
+
error: message`No remaining parsers could match the input.`
|
|
1300
|
+
};
|
|
1301
|
+
const stateArray = currentContext.state;
|
|
1302
|
+
const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
1303
|
+
for (const [parser, index] of remainingParsers) {
|
|
1304
|
+
const result = parser.parse({
|
|
1305
|
+
...currentContext,
|
|
1306
|
+
state: stateArray[index]
|
|
1307
|
+
});
|
|
1308
|
+
if (result.success && result.consumed.length > 0) {
|
|
1309
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
1310
|
+
currentContext = {
|
|
1311
|
+
...currentContext,
|
|
1312
|
+
buffer: result.next.buffer,
|
|
1313
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1314
|
+
state: newStateArray
|
|
1315
|
+
};
|
|
1316
|
+
allConsumed.push(...result.consumed);
|
|
1317
|
+
matchedParsers.add(index);
|
|
1318
|
+
foundMatch = true;
|
|
1319
|
+
break;
|
|
1320
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
1321
|
+
}
|
|
1322
|
+
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
1323
|
+
const result = parser.parse({
|
|
1324
|
+
...currentContext,
|
|
1325
|
+
state: stateArray[index]
|
|
1326
|
+
});
|
|
1327
|
+
if (result.success && result.consumed.length < 1) {
|
|
1328
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
1329
|
+
currentContext = {
|
|
1330
|
+
...currentContext,
|
|
1331
|
+
state: newStateArray
|
|
1332
|
+
};
|
|
1333
|
+
matchedParsers.add(index);
|
|
1334
|
+
foundMatch = true;
|
|
1335
|
+
break;
|
|
1336
|
+
} else if (!result.success && result.consumed < 1) {
|
|
1337
|
+
matchedParsers.add(index);
|
|
1338
|
+
foundMatch = true;
|
|
1339
|
+
break;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (!foundMatch) return {
|
|
1343
|
+
...error,
|
|
1344
|
+
success: false
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
return {
|
|
1348
|
+
success: true,
|
|
1349
|
+
next: currentContext,
|
|
1350
|
+
consumed: allConsumed
|
|
1351
|
+
};
|
|
1352
|
+
};
|
|
1353
|
+
const parseAsync = async (context) => {
|
|
1354
|
+
let currentContext = context;
|
|
1355
|
+
const allConsumed = [];
|
|
1356
|
+
const matchedParsers = /* @__PURE__ */ new Set();
|
|
1357
|
+
while (matchedParsers.size < parsers.length) {
|
|
1358
|
+
let foundMatch = false;
|
|
1359
|
+
let error = {
|
|
1360
|
+
consumed: 0,
|
|
1361
|
+
error: message`No remaining parsers could match the input.`
|
|
1362
|
+
};
|
|
1363
|
+
const stateArray = currentContext.state;
|
|
1364
|
+
const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
1365
|
+
for (const [parser, index] of remainingParsers) {
|
|
1366
|
+
const result = await parser.parse({
|
|
1367
|
+
...currentContext,
|
|
1368
|
+
state: stateArray[index]
|
|
1369
|
+
});
|
|
1370
|
+
if (result.success && result.consumed.length > 0) {
|
|
1371
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
1372
|
+
currentContext = {
|
|
1373
|
+
...currentContext,
|
|
1374
|
+
buffer: result.next.buffer,
|
|
1375
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1376
|
+
state: newStateArray
|
|
1377
|
+
};
|
|
1378
|
+
allConsumed.push(...result.consumed);
|
|
1379
|
+
matchedParsers.add(index);
|
|
1380
|
+
foundMatch = true;
|
|
1381
|
+
break;
|
|
1382
|
+
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
1383
|
+
}
|
|
1384
|
+
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
1385
|
+
const result = await parser.parse({
|
|
1386
|
+
...currentContext,
|
|
1387
|
+
state: stateArray[index]
|
|
1388
|
+
});
|
|
1389
|
+
if (result.success && result.consumed.length < 1) {
|
|
1390
|
+
const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
|
|
1391
|
+
currentContext = {
|
|
1392
|
+
...currentContext,
|
|
1393
|
+
state: newStateArray
|
|
1394
|
+
};
|
|
1395
|
+
matchedParsers.add(index);
|
|
1396
|
+
foundMatch = true;
|
|
1397
|
+
break;
|
|
1398
|
+
} else if (!result.success && result.consumed < 1) {
|
|
1399
|
+
matchedParsers.add(index);
|
|
1400
|
+
foundMatch = true;
|
|
1401
|
+
break;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
if (!foundMatch) return {
|
|
1405
|
+
...error,
|
|
1406
|
+
success: false
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
return {
|
|
1410
|
+
success: true,
|
|
1411
|
+
next: currentContext,
|
|
1412
|
+
consumed: allConsumed
|
|
1413
|
+
};
|
|
1414
|
+
};
|
|
1415
|
+
const completeSync = (state) => {
|
|
1416
|
+
const results = [];
|
|
1417
|
+
const stateArray = state;
|
|
1418
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
1419
|
+
const parser = syncParsers[i];
|
|
1420
|
+
const parserState = stateArray[i];
|
|
1421
|
+
const result = parser.complete(parserState);
|
|
1422
|
+
if (!result.success) return result;
|
|
1423
|
+
if (Array.isArray(result.value)) results.push(...result.value);
|
|
1424
|
+
else results.push(result.value);
|
|
1425
|
+
}
|
|
1426
|
+
return {
|
|
1427
|
+
success: true,
|
|
1428
|
+
value: results
|
|
1429
|
+
};
|
|
1430
|
+
};
|
|
1431
|
+
const completeAsync = async (state) => {
|
|
1432
|
+
const results = [];
|
|
1433
|
+
const stateArray = state;
|
|
1434
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1435
|
+
const parser = parsers[i];
|
|
1436
|
+
const parserState = stateArray[i];
|
|
1437
|
+
const result = await parser.complete(parserState);
|
|
1438
|
+
if (!result.success) return result;
|
|
1439
|
+
if (Array.isArray(result.value)) results.push(...result.value);
|
|
1440
|
+
else results.push(result.value);
|
|
1441
|
+
}
|
|
1442
|
+
return {
|
|
1443
|
+
success: true,
|
|
1444
|
+
value: results
|
|
1445
|
+
};
|
|
1446
|
+
};
|
|
842
1447
|
return {
|
|
1448
|
+
$mode: combinedMode,
|
|
843
1449
|
$valueType: [],
|
|
844
1450
|
$stateType: [],
|
|
845
1451
|
priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
|
|
846
1452
|
usage: parsers.flatMap((p) => p.usage),
|
|
847
1453
|
initialState,
|
|
848
1454
|
parse(context) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const matchedParsers = /* @__PURE__ */ new Set();
|
|
852
|
-
while (matchedParsers.size < parsers.length) {
|
|
853
|
-
let foundMatch = false;
|
|
854
|
-
let error = {
|
|
855
|
-
consumed: 0,
|
|
856
|
-
error: message`No remaining parsers could match the input.`
|
|
857
|
-
};
|
|
858
|
-
const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
|
|
859
|
-
for (const [parser, index] of remainingParsers) {
|
|
860
|
-
const result = parser.parse({
|
|
861
|
-
...currentContext,
|
|
862
|
-
state: currentContext.state[index]
|
|
863
|
-
});
|
|
864
|
-
if (result.success && result.consumed.length > 0) {
|
|
865
|
-
currentContext = {
|
|
866
|
-
...currentContext,
|
|
867
|
-
buffer: result.next.buffer,
|
|
868
|
-
optionsTerminated: result.next.optionsTerminated,
|
|
869
|
-
state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
|
|
870
|
-
};
|
|
871
|
-
allConsumed.push(...result.consumed);
|
|
872
|
-
matchedParsers.add(index);
|
|
873
|
-
foundMatch = true;
|
|
874
|
-
break;
|
|
875
|
-
} else if (!result.success && error.consumed < result.consumed) error = result;
|
|
876
|
-
}
|
|
877
|
-
if (!foundMatch) for (const [parser, index] of remainingParsers) {
|
|
878
|
-
const result = parser.parse({
|
|
879
|
-
...currentContext,
|
|
880
|
-
state: currentContext.state[index]
|
|
881
|
-
});
|
|
882
|
-
if (result.success && result.consumed.length < 1) {
|
|
883
|
-
currentContext = {
|
|
884
|
-
...currentContext,
|
|
885
|
-
state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
|
|
886
|
-
};
|
|
887
|
-
matchedParsers.add(index);
|
|
888
|
-
foundMatch = true;
|
|
889
|
-
break;
|
|
890
|
-
} else if (!result.success && result.consumed < 1) {
|
|
891
|
-
matchedParsers.add(index);
|
|
892
|
-
foundMatch = true;
|
|
893
|
-
break;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
if (!foundMatch) return {
|
|
897
|
-
...error,
|
|
898
|
-
success: false
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
|
-
return {
|
|
902
|
-
success: true,
|
|
903
|
-
next: currentContext,
|
|
904
|
-
consumed: allConsumed
|
|
905
|
-
};
|
|
1455
|
+
if (isAsync) return parseAsync(context);
|
|
1456
|
+
return parseSync(context);
|
|
906
1457
|
},
|
|
907
1458
|
complete(state) {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
const parser = parsers[i];
|
|
911
|
-
const parserState = state[i];
|
|
912
|
-
const result = parser.complete(parserState);
|
|
913
|
-
if (!result.success) return result;
|
|
914
|
-
if (Array.isArray(result.value)) results.push(...result.value);
|
|
915
|
-
else results.push(result.value);
|
|
916
|
-
}
|
|
917
|
-
return {
|
|
918
|
-
success: true,
|
|
919
|
-
value: results
|
|
920
|
-
};
|
|
1459
|
+
if (isAsync) return completeAsync(state);
|
|
1460
|
+
return completeSync(state);
|
|
921
1461
|
},
|
|
922
1462
|
suggest(context, prefix) {
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1463
|
+
const stateArray = context.state;
|
|
1464
|
+
if (isAsync) return async function* () {
|
|
1465
|
+
const suggestions = [];
|
|
1466
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1467
|
+
const parser = parsers[i];
|
|
1468
|
+
const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
|
|
1469
|
+
const parserSuggestions = parser.suggest({
|
|
1470
|
+
...context,
|
|
1471
|
+
state: parserState
|
|
1472
|
+
}, prefix);
|
|
1473
|
+
if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
|
|
1474
|
+
else suggestions.push(...parserSuggestions);
|
|
1475
|
+
}
|
|
1476
|
+
yield* deduplicateSuggestions(suggestions);
|
|
1477
|
+
}();
|
|
1478
|
+
return function* () {
|
|
1479
|
+
const suggestions = [];
|
|
1480
|
+
for (let i = 0; i < syncParsers.length; i++) {
|
|
1481
|
+
const parser = syncParsers[i];
|
|
1482
|
+
const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
|
|
1483
|
+
const parserSuggestions = parser.suggest({
|
|
1484
|
+
...context,
|
|
1485
|
+
state: parserState
|
|
1486
|
+
}, prefix);
|
|
1487
|
+
suggestions.push(...parserSuggestions);
|
|
1488
|
+
}
|
|
1489
|
+
yield* deduplicateSuggestions(suggestions);
|
|
1490
|
+
}();
|
|
934
1491
|
},
|
|
935
1492
|
getDocFragments(state, _defaultValue) {
|
|
936
|
-
const fragments =
|
|
1493
|
+
const fragments = syncParsers.flatMap((p, index) => {
|
|
937
1494
|
const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
|
|
938
1495
|
kind: "available",
|
|
939
1496
|
state: state.state[index]
|
|
@@ -1003,6 +1560,7 @@ function concat(...parsers) {
|
|
|
1003
1560
|
*/
|
|
1004
1561
|
function group(label, parser) {
|
|
1005
1562
|
return {
|
|
1563
|
+
$mode: parser.$mode,
|
|
1006
1564
|
$valueType: parser.$valueType,
|
|
1007
1565
|
$stateType: parser.$stateType,
|
|
1008
1566
|
priority: parser.priority,
|
|
@@ -1068,6 +1626,8 @@ function group(label, parser) {
|
|
|
1068
1626
|
function conditional(discriminator, branches, defaultBranch, options) {
|
|
1069
1627
|
const branchParsers = Object.entries(branches);
|
|
1070
1628
|
const allBranchParsers = defaultBranch ? [...branchParsers.map(([_, p]) => p), defaultBranch] : branchParsers.map(([_, p]) => p);
|
|
1629
|
+
const combinedMode = discriminator.$mode === "async" || allBranchParsers.some((p) => p.$mode === "async") ? "async" : "sync";
|
|
1630
|
+
const isAsync = combinedMode === "async";
|
|
1071
1631
|
const maxPriority = Math.max(discriminator.priority, ...allBranchParsers.map((p) => p.priority));
|
|
1072
1632
|
function appendLiteralToUsage(usage$1, literalValue) {
|
|
1073
1633
|
const result = [];
|
|
@@ -1105,164 +1665,334 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
1105
1665
|
selectedBranch: void 0,
|
|
1106
1666
|
branchState: void 0
|
|
1107
1667
|
};
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
initialState
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
state: state.branchState,
|
|
1121
|
-
usage: branchParser.usage
|
|
1122
|
-
});
|
|
1123
|
-
if (branchResult.success) return {
|
|
1124
|
-
success: true,
|
|
1125
|
-
next: {
|
|
1126
|
-
...branchResult.next,
|
|
1127
|
-
state: {
|
|
1128
|
-
...state,
|
|
1129
|
-
branchState: branchResult.next.state
|
|
1130
|
-
}
|
|
1131
|
-
},
|
|
1132
|
-
consumed: branchResult.consumed
|
|
1133
|
-
};
|
|
1134
|
-
return branchResult;
|
|
1135
|
-
}
|
|
1136
|
-
const discriminatorResult = discriminator.parse({
|
|
1668
|
+
const getNoMatchError$1 = () => {
|
|
1669
|
+
const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
|
|
1670
|
+
return options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
|
|
1671
|
+
};
|
|
1672
|
+
const parseSync = (context) => {
|
|
1673
|
+
const state = context.state ?? initialState;
|
|
1674
|
+
const syncDiscriminator = discriminator;
|
|
1675
|
+
const syncBranches = branches;
|
|
1676
|
+
const syncDefaultBranch = defaultBranch;
|
|
1677
|
+
if (state.selectedBranch !== void 0) {
|
|
1678
|
+
const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
|
|
1679
|
+
const branchResult = branchParser.parse({
|
|
1137
1680
|
...context,
|
|
1138
|
-
state: state.
|
|
1681
|
+
state: state.branchState,
|
|
1682
|
+
usage: branchParser.usage
|
|
1139
1683
|
});
|
|
1140
|
-
if (
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
...context,
|
|
1148
|
-
buffer: discriminatorResult.next.buffer,
|
|
1149
|
-
optionsTerminated: discriminatorResult.next.optionsTerminated,
|
|
1150
|
-
state: branchParser.initialState,
|
|
1151
|
-
usage: branchParser.usage
|
|
1152
|
-
});
|
|
1153
|
-
if (branchParseResult.success) return {
|
|
1154
|
-
success: true,
|
|
1155
|
-
next: {
|
|
1156
|
-
...branchParseResult.next,
|
|
1157
|
-
state: {
|
|
1158
|
-
discriminatorState: discriminatorResult.next.state,
|
|
1159
|
-
discriminatorValue: value,
|
|
1160
|
-
selectedBranch: {
|
|
1161
|
-
kind: "branch",
|
|
1162
|
-
key: value
|
|
1163
|
-
},
|
|
1164
|
-
branchState: branchParseResult.next.state
|
|
1165
|
-
}
|
|
1166
|
-
},
|
|
1167
|
-
consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
|
|
1168
|
-
};
|
|
1169
|
-
return {
|
|
1170
|
-
success: true,
|
|
1171
|
-
next: {
|
|
1172
|
-
...discriminatorResult.next,
|
|
1173
|
-
state: {
|
|
1174
|
-
discriminatorState: discriminatorResult.next.state,
|
|
1175
|
-
discriminatorValue: value,
|
|
1176
|
-
selectedBranch: {
|
|
1177
|
-
kind: "branch",
|
|
1178
|
-
key: value
|
|
1179
|
-
},
|
|
1180
|
-
branchState: branchParser.initialState
|
|
1181
|
-
}
|
|
1182
|
-
},
|
|
1183
|
-
consumed: discriminatorResult.consumed
|
|
1184
|
-
};
|
|
1684
|
+
if (branchResult.success) return {
|
|
1685
|
+
success: true,
|
|
1686
|
+
next: {
|
|
1687
|
+
...branchResult.next,
|
|
1688
|
+
state: {
|
|
1689
|
+
...state,
|
|
1690
|
+
branchState: branchResult.next.state
|
|
1185
1691
|
}
|
|
1692
|
+
},
|
|
1693
|
+
consumed: branchResult.consumed
|
|
1694
|
+
};
|
|
1695
|
+
return branchResult;
|
|
1696
|
+
}
|
|
1697
|
+
const discriminatorResult = syncDiscriminator.parse({
|
|
1698
|
+
...context,
|
|
1699
|
+
state: state.discriminatorState
|
|
1700
|
+
});
|
|
1701
|
+
if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
|
|
1702
|
+
const completionResult = syncDiscriminator.complete(discriminatorResult.next.state);
|
|
1703
|
+
if (completionResult.success) {
|
|
1704
|
+
const value = completionResult.value;
|
|
1705
|
+
const branchParser = syncBranches[value];
|
|
1706
|
+
if (branchParser) {
|
|
1707
|
+
const branchParseResult = branchParser.parse({
|
|
1708
|
+
...context,
|
|
1709
|
+
buffer: discriminatorResult.next.buffer,
|
|
1710
|
+
optionsTerminated: discriminatorResult.next.optionsTerminated,
|
|
1711
|
+
state: branchParser.initialState,
|
|
1712
|
+
usage: branchParser.usage
|
|
1713
|
+
});
|
|
1714
|
+
if (branchParseResult.success) return {
|
|
1715
|
+
success: true,
|
|
1716
|
+
next: {
|
|
1717
|
+
...branchParseResult.next,
|
|
1718
|
+
state: {
|
|
1719
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1720
|
+
discriminatorValue: value,
|
|
1721
|
+
selectedBranch: {
|
|
1722
|
+
kind: "branch",
|
|
1723
|
+
key: value
|
|
1724
|
+
},
|
|
1725
|
+
branchState: branchParseResult.next.state
|
|
1726
|
+
}
|
|
1727
|
+
},
|
|
1728
|
+
consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
|
|
1729
|
+
};
|
|
1730
|
+
return {
|
|
1731
|
+
success: true,
|
|
1732
|
+
next: {
|
|
1733
|
+
...discriminatorResult.next,
|
|
1734
|
+
state: {
|
|
1735
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1736
|
+
discriminatorValue: value,
|
|
1737
|
+
selectedBranch: {
|
|
1738
|
+
kind: "branch",
|
|
1739
|
+
key: value
|
|
1740
|
+
},
|
|
1741
|
+
branchState: branchParser.initialState
|
|
1742
|
+
}
|
|
1743
|
+
},
|
|
1744
|
+
consumed: discriminatorResult.consumed
|
|
1745
|
+
};
|
|
1186
1746
|
}
|
|
1187
1747
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
}
|
|
1207
|
-
const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
|
|
1208
|
-
const errorMessage = options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
|
|
1209
|
-
return {
|
|
1210
|
-
success: false,
|
|
1211
|
-
consumed: 0,
|
|
1212
|
-
error: errorMessage
|
|
1748
|
+
}
|
|
1749
|
+
if (syncDefaultBranch !== void 0) {
|
|
1750
|
+
const defaultResult = syncDefaultBranch.parse({
|
|
1751
|
+
...context,
|
|
1752
|
+
state: state.branchState ?? syncDefaultBranch.initialState,
|
|
1753
|
+
usage: syncDefaultBranch.usage
|
|
1754
|
+
});
|
|
1755
|
+
if (defaultResult.success && defaultResult.consumed.length > 0) return {
|
|
1756
|
+
success: true,
|
|
1757
|
+
next: {
|
|
1758
|
+
...defaultResult.next,
|
|
1759
|
+
state: {
|
|
1760
|
+
...state,
|
|
1761
|
+
selectedBranch: { kind: "default" },
|
|
1762
|
+
branchState: defaultResult.next.state
|
|
1763
|
+
}
|
|
1764
|
+
},
|
|
1765
|
+
consumed: defaultResult.consumed
|
|
1213
1766
|
};
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1767
|
+
}
|
|
1768
|
+
return {
|
|
1769
|
+
success: false,
|
|
1770
|
+
consumed: 0,
|
|
1771
|
+
error: getNoMatchError$1()
|
|
1772
|
+
};
|
|
1773
|
+
};
|
|
1774
|
+
const parseAsync = async (context) => {
|
|
1775
|
+
const state = context.state ?? initialState;
|
|
1776
|
+
if (state.selectedBranch !== void 0) {
|
|
1777
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1778
|
+
const branchResult = await branchParser.parse({
|
|
1779
|
+
...context,
|
|
1780
|
+
state: state.branchState,
|
|
1781
|
+
usage: branchParser.usage
|
|
1782
|
+
});
|
|
1783
|
+
if (branchResult.success) return {
|
|
1784
|
+
success: true,
|
|
1785
|
+
next: {
|
|
1786
|
+
...branchResult.next,
|
|
1787
|
+
state: {
|
|
1788
|
+
...state,
|
|
1789
|
+
branchState: branchResult.next.state
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
consumed: branchResult.consumed
|
|
1793
|
+
};
|
|
1794
|
+
return branchResult;
|
|
1795
|
+
}
|
|
1796
|
+
const discriminatorResult = await discriminator.parse({
|
|
1797
|
+
...context,
|
|
1798
|
+
state: state.discriminatorState
|
|
1799
|
+
});
|
|
1800
|
+
if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
|
|
1801
|
+
const completionResult = await discriminator.complete(discriminatorResult.next.state);
|
|
1802
|
+
if (completionResult.success) {
|
|
1803
|
+
const value = completionResult.value;
|
|
1804
|
+
const branchParser = branches[value];
|
|
1805
|
+
if (branchParser) {
|
|
1806
|
+
const branchParseResult = await branchParser.parse({
|
|
1807
|
+
...context,
|
|
1808
|
+
buffer: discriminatorResult.next.buffer,
|
|
1809
|
+
optionsTerminated: discriminatorResult.next.optionsTerminated,
|
|
1810
|
+
state: branchParser.initialState,
|
|
1811
|
+
usage: branchParser.usage
|
|
1812
|
+
});
|
|
1813
|
+
if (branchParseResult.success) return {
|
|
1814
|
+
success: true,
|
|
1815
|
+
next: {
|
|
1816
|
+
...branchParseResult.next,
|
|
1817
|
+
state: {
|
|
1818
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1819
|
+
discriminatorValue: value,
|
|
1820
|
+
selectedBranch: {
|
|
1821
|
+
kind: "branch",
|
|
1822
|
+
key: value
|
|
1823
|
+
},
|
|
1824
|
+
branchState: branchParseResult.next.state
|
|
1825
|
+
}
|
|
1826
|
+
},
|
|
1827
|
+
consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
|
|
1828
|
+
};
|
|
1221
1829
|
return {
|
|
1222
1830
|
success: true,
|
|
1223
|
-
|
|
1831
|
+
next: {
|
|
1832
|
+
...discriminatorResult.next,
|
|
1833
|
+
state: {
|
|
1834
|
+
discriminatorState: discriminatorResult.next.state,
|
|
1835
|
+
discriminatorValue: value,
|
|
1836
|
+
selectedBranch: {
|
|
1837
|
+
kind: "branch",
|
|
1838
|
+
key: value
|
|
1839
|
+
},
|
|
1840
|
+
branchState: branchParser.initialState
|
|
1841
|
+
}
|
|
1842
|
+
},
|
|
1843
|
+
consumed: discriminatorResult.consumed
|
|
1224
1844
|
};
|
|
1225
1845
|
}
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
if (defaultBranch !== void 0) {
|
|
1849
|
+
const defaultResult = await defaultBranch.parse({
|
|
1850
|
+
...context,
|
|
1851
|
+
state: state.branchState ?? defaultBranch.initialState,
|
|
1852
|
+
usage: defaultBranch.usage
|
|
1853
|
+
});
|
|
1854
|
+
if (defaultResult.success && defaultResult.consumed.length > 0) return {
|
|
1855
|
+
success: true,
|
|
1856
|
+
next: {
|
|
1857
|
+
...defaultResult.next,
|
|
1858
|
+
state: {
|
|
1859
|
+
...state,
|
|
1860
|
+
selectedBranch: { kind: "default" },
|
|
1861
|
+
branchState: defaultResult.next.state
|
|
1862
|
+
}
|
|
1863
|
+
},
|
|
1864
|
+
consumed: defaultResult.consumed
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
return {
|
|
1868
|
+
success: false,
|
|
1869
|
+
consumed: 0,
|
|
1870
|
+
error: getNoMatchError$1()
|
|
1871
|
+
};
|
|
1872
|
+
};
|
|
1873
|
+
const completeSync = (state) => {
|
|
1874
|
+
const syncDefaultBranch = defaultBranch;
|
|
1875
|
+
const syncBranches = branches;
|
|
1876
|
+
if (state.selectedBranch === void 0) {
|
|
1877
|
+
if (syncDefaultBranch !== void 0) {
|
|
1878
|
+
const branchState = state.branchState ?? syncDefaultBranch.initialState;
|
|
1879
|
+
const defaultResult = syncDefaultBranch.complete(branchState);
|
|
1880
|
+
if (!defaultResult.success) return defaultResult;
|
|
1226
1881
|
return {
|
|
1227
|
-
success:
|
|
1228
|
-
|
|
1882
|
+
success: true,
|
|
1883
|
+
value: [void 0, defaultResult.value]
|
|
1229
1884
|
};
|
|
1230
1885
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1886
|
+
return {
|
|
1887
|
+
success: false,
|
|
1888
|
+
error: message`Missing required discriminator option.`
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
|
|
1892
|
+
const branchResult = branchParser.complete(state.branchState);
|
|
1893
|
+
if (!branchResult.success) {
|
|
1894
|
+
if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
|
|
1895
|
+
success: false,
|
|
1896
|
+
error: options.errors.branchError(state.discriminatorValue, branchResult.error)
|
|
1897
|
+
};
|
|
1898
|
+
return branchResult;
|
|
1899
|
+
}
|
|
1900
|
+
const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
|
|
1901
|
+
return {
|
|
1902
|
+
success: true,
|
|
1903
|
+
value: [discriminatorValue, branchResult.value]
|
|
1904
|
+
};
|
|
1905
|
+
};
|
|
1906
|
+
const completeAsync = async (state) => {
|
|
1907
|
+
if (state.selectedBranch === void 0) {
|
|
1908
|
+
if (defaultBranch !== void 0) {
|
|
1909
|
+
const branchState = state.branchState ?? defaultBranch.initialState;
|
|
1910
|
+
const defaultResult = await defaultBranch.complete(branchState);
|
|
1911
|
+
if (!defaultResult.success) return defaultResult;
|
|
1912
|
+
return {
|
|
1913
|
+
success: true,
|
|
1914
|
+
value: [void 0, defaultResult.value]
|
|
1237
1915
|
};
|
|
1238
|
-
return branchResult;
|
|
1239
1916
|
}
|
|
1240
|
-
const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
|
|
1241
1917
|
return {
|
|
1242
|
-
success:
|
|
1243
|
-
|
|
1918
|
+
success: false,
|
|
1919
|
+
error: message`Missing required discriminator option.`
|
|
1244
1920
|
};
|
|
1921
|
+
}
|
|
1922
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1923
|
+
const branchResult = await branchParser.complete(state.branchState);
|
|
1924
|
+
if (!branchResult.success) {
|
|
1925
|
+
if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
|
|
1926
|
+
success: false,
|
|
1927
|
+
error: options.errors.branchError(state.discriminatorValue, branchResult.error)
|
|
1928
|
+
};
|
|
1929
|
+
return branchResult;
|
|
1930
|
+
}
|
|
1931
|
+
const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
|
|
1932
|
+
return {
|
|
1933
|
+
success: true,
|
|
1934
|
+
value: [discriminatorValue, branchResult.value]
|
|
1935
|
+
};
|
|
1936
|
+
};
|
|
1937
|
+
function* suggestSync(context, prefix) {
|
|
1938
|
+
const state = context.state ?? initialState;
|
|
1939
|
+
const syncDiscriminator = discriminator;
|
|
1940
|
+
const syncBranches = branches;
|
|
1941
|
+
const syncDefaultBranch = defaultBranch;
|
|
1942
|
+
if (state.selectedBranch === void 0) {
|
|
1943
|
+
yield* syncDiscriminator.suggest({
|
|
1944
|
+
...context,
|
|
1945
|
+
state: state.discriminatorState
|
|
1946
|
+
}, prefix);
|
|
1947
|
+
if (syncDefaultBranch !== void 0) yield* syncDefaultBranch.suggest({
|
|
1948
|
+
...context,
|
|
1949
|
+
state: state.branchState ?? syncDefaultBranch.initialState
|
|
1950
|
+
}, prefix);
|
|
1951
|
+
} else {
|
|
1952
|
+
const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
|
|
1953
|
+
yield* branchParser.suggest({
|
|
1954
|
+
...context,
|
|
1955
|
+
state: state.branchState
|
|
1956
|
+
}, prefix);
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
async function* suggestAsync(context, prefix) {
|
|
1960
|
+
const state = context.state ?? initialState;
|
|
1961
|
+
if (state.selectedBranch === void 0) {
|
|
1962
|
+
yield* discriminator.suggest({
|
|
1963
|
+
...context,
|
|
1964
|
+
state: state.discriminatorState
|
|
1965
|
+
}, prefix);
|
|
1966
|
+
if (defaultBranch !== void 0) yield* defaultBranch.suggest({
|
|
1967
|
+
...context,
|
|
1968
|
+
state: state.branchState ?? defaultBranch.initialState
|
|
1969
|
+
}, prefix);
|
|
1970
|
+
} else {
|
|
1971
|
+
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1972
|
+
yield* branchParser.suggest({
|
|
1973
|
+
...context,
|
|
1974
|
+
state: state.branchState
|
|
1975
|
+
}, prefix);
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
return {
|
|
1979
|
+
$mode: combinedMode,
|
|
1980
|
+
$valueType: [],
|
|
1981
|
+
$stateType: [],
|
|
1982
|
+
priority: maxPriority,
|
|
1983
|
+
usage,
|
|
1984
|
+
initialState,
|
|
1985
|
+
parse(context) {
|
|
1986
|
+
if (isAsync) return parseAsync(context);
|
|
1987
|
+
return parseSync(context);
|
|
1988
|
+
},
|
|
1989
|
+
complete(state) {
|
|
1990
|
+
if (isAsync) return completeAsync(state);
|
|
1991
|
+
return completeSync(state);
|
|
1245
1992
|
},
|
|
1246
1993
|
suggest(context, prefix) {
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
if (state.selectedBranch === void 0) {
|
|
1250
|
-
suggestions.push(...discriminator.suggest({
|
|
1251
|
-
...context,
|
|
1252
|
-
state: state.discriminatorState
|
|
1253
|
-
}, prefix));
|
|
1254
|
-
if (defaultBranch !== void 0) suggestions.push(...defaultBranch.suggest({
|
|
1255
|
-
...context,
|
|
1256
|
-
state: state.branchState ?? defaultBranch.initialState
|
|
1257
|
-
}, prefix));
|
|
1258
|
-
} else {
|
|
1259
|
-
const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
|
|
1260
|
-
suggestions.push(...branchParser.suggest({
|
|
1261
|
-
...context,
|
|
1262
|
-
state: state.branchState
|
|
1263
|
-
}, prefix));
|
|
1264
|
-
}
|
|
1265
|
-
return deduplicateSuggestions(suggestions);
|
|
1994
|
+
if (isAsync) return suggestAsync(context, prefix);
|
|
1995
|
+
return suggestSync(context, prefix);
|
|
1266
1996
|
},
|
|
1267
1997
|
getDocFragments(_state, _defaultValue) {
|
|
1268
1998
|
const fragments = [];
|