@optique/core 1.0.2 → 1.0.5
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 +124 -41
- package/dist/constructs.js +124 -41
- package/dist/primitives.cjs +26 -17
- package/dist/primitives.js +26 -17
- package/package.json +1 -1
package/dist/constructs.cjs
CHANGED
|
@@ -516,6 +516,35 @@ function createExclusiveState(parentState, index, parser, result) {
|
|
|
516
516
|
return require_annotations.annotateFreshArray(parentState, [index, annotatedResult]);
|
|
517
517
|
}
|
|
518
518
|
/**
|
|
519
|
+
* Detects a branch result that handled only the global options terminator.
|
|
520
|
+
* Such a result advances the shared parser context, but does not identify
|
|
521
|
+
* which exclusive branch matched.
|
|
522
|
+
* @internal
|
|
523
|
+
*/
|
|
524
|
+
function isOptionsTerminatorOnlyResult(context, result) {
|
|
525
|
+
return !context.optionsTerminated && context.buffer[0] === "--" && result.success && result.next.optionsTerminated && result.consumed.length === 1 && result.consumed[0] === "--";
|
|
526
|
+
}
|
|
527
|
+
function isUnselectedBooleanOptionState(state) {
|
|
528
|
+
return state != null && typeof state === "object" && "success" in state && state.success === true && "value" in state && state.value === false;
|
|
529
|
+
}
|
|
530
|
+
function preserveExclusiveStateAfterOptionsTerminator(context, result) {
|
|
531
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, result.next.exec);
|
|
532
|
+
return {
|
|
533
|
+
success: true,
|
|
534
|
+
next: {
|
|
535
|
+
...context,
|
|
536
|
+
buffer: result.next.buffer,
|
|
537
|
+
optionsTerminated: true,
|
|
538
|
+
state: context.state,
|
|
539
|
+
...mergedExec != null ? {
|
|
540
|
+
exec: mergedExec,
|
|
541
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
542
|
+
} : {}
|
|
543
|
+
},
|
|
544
|
+
consumed: result.consumed
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
519
548
|
* Creates a complete() method shared by or() and longestMatch().
|
|
520
549
|
* @internal
|
|
521
550
|
*/
|
|
@@ -752,9 +781,15 @@ function or(...args) {
|
|
|
752
781
|
let zeroConsumedBranch = null;
|
|
753
782
|
let zeroConsumedCount = 0;
|
|
754
783
|
let provisionalConsuming = null;
|
|
784
|
+
let optionsTerminatorResult = null;
|
|
755
785
|
let provisionalAmbiguous = false;
|
|
756
786
|
for (const [parser, i] of orderedParsers) {
|
|
757
787
|
const result = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
|
|
788
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
789
|
+
if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
|
|
790
|
+
optionsTerminatorResult ??= result;
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
758
793
|
if (result.success && result.consumed.length > 0) {
|
|
759
794
|
if (result.provisional) {
|
|
760
795
|
const activeBranchLocked = activeState != null && activeState[1].success && activeState[1].consumed.length > 0;
|
|
@@ -935,6 +970,7 @@ function or(...args) {
|
|
|
935
970
|
}
|
|
936
971
|
}
|
|
937
972
|
}
|
|
973
|
+
if (optionsTerminatorResult != null) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorResult);
|
|
938
974
|
return {
|
|
939
975
|
...error,
|
|
940
976
|
success: false
|
|
@@ -948,10 +984,16 @@ function or(...args) {
|
|
|
948
984
|
let zeroConsumedBranch = null;
|
|
949
985
|
let zeroConsumedCount = 0;
|
|
950
986
|
let provisionalConsuming = null;
|
|
987
|
+
let optionsTerminatorResult = null;
|
|
951
988
|
let provisionalAmbiguous = false;
|
|
952
989
|
for (const [parser, i] of orderedParsers) {
|
|
953
990
|
const resultOrPromise = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
|
|
954
991
|
const result = await resultOrPromise;
|
|
992
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
993
|
+
if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
|
|
994
|
+
optionsTerminatorResult ??= result;
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
955
997
|
if (result.success && result.consumed.length > 0) {
|
|
956
998
|
if (result.provisional) {
|
|
957
999
|
const activeBranchLocked = activeState != null && activeState[1].success && activeState[1].consumed.length > 0;
|
|
@@ -1134,6 +1176,7 @@ function or(...args) {
|
|
|
1134
1176
|
}
|
|
1135
1177
|
}
|
|
1136
1178
|
}
|
|
1179
|
+
if (optionsTerminatorResult != null) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorResult);
|
|
1137
1180
|
return {
|
|
1138
1181
|
...error,
|
|
1139
1182
|
success: false
|
|
@@ -1221,82 +1264,122 @@ function longestMatch(...args) {
|
|
|
1221
1264
|
return createUnexpectedInputErrorWithScopedSuggestions(defaultMsg, token, parsers, options?.errors?.suggestions);
|
|
1222
1265
|
})()
|
|
1223
1266
|
});
|
|
1224
|
-
const
|
|
1267
|
+
const commitLongestMatch = (context, match, optionsTerminatorResult) => {
|
|
1268
|
+
const selectedResult = optionsTerminatorResult == null ? match.result : {
|
|
1269
|
+
...match.result,
|
|
1270
|
+
next: {
|
|
1271
|
+
...match.result.next,
|
|
1272
|
+
buffer: optionsTerminatorResult.next.buffer,
|
|
1273
|
+
optionsTerminated: true
|
|
1274
|
+
},
|
|
1275
|
+
consumed: [...optionsTerminatorResult.consumed, ...match.result.consumed]
|
|
1276
|
+
};
|
|
1277
|
+
const parser = parsers[match.index];
|
|
1278
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, selectedResult.next.exec);
|
|
1279
|
+
return {
|
|
1280
|
+
success: true,
|
|
1281
|
+
next: {
|
|
1282
|
+
...context,
|
|
1283
|
+
buffer: selectedResult.next.buffer,
|
|
1284
|
+
optionsTerminated: selectedResult.next.optionsTerminated,
|
|
1285
|
+
state: createExclusiveState(context.state, match.index, parser, selectedResult),
|
|
1286
|
+
...mergedExec != null ? {
|
|
1287
|
+
exec: mergedExec,
|
|
1288
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1289
|
+
} : {}
|
|
1290
|
+
},
|
|
1291
|
+
consumed: selectedResult.consumed
|
|
1292
|
+
};
|
|
1293
|
+
};
|
|
1294
|
+
const resolveLongestMatchOptionsTerminator = (context, bestMatch, optionsTerminatorMatches) => {
|
|
1295
|
+
if (optionsTerminatorMatches.length < 1) return null;
|
|
1296
|
+
if (bestMatch != null && bestMatch.consumed > 0) return null;
|
|
1297
|
+
const activeState = normalizeExclusiveState(context.state);
|
|
1298
|
+
if (activeState != null && activeState[1].success && activeState[1].consumed.length > 0) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorMatches[0].result);
|
|
1299
|
+
let selected = bestMatch == null ? null : {
|
|
1300
|
+
match: bestMatch,
|
|
1301
|
+
fromTerminator: false
|
|
1302
|
+
};
|
|
1303
|
+
for (const match of optionsTerminatorMatches) {
|
|
1304
|
+
if (!match.selectedAfterTerminator && (extractRequiredUsage(parsers[match.index].usage).length > 0 || isUnselectedBooleanOptionState(match.result.next.state))) continue;
|
|
1305
|
+
const selectedIsProvisional = selected != null && !!selected.match.result.provisional;
|
|
1306
|
+
const matchIsProvisional = !!match.result.provisional;
|
|
1307
|
+
if (selected == null || selectedIsProvisional && !matchIsProvisional || selectedIsProvisional === matchIsProvisional && match.index < selected.match.index) selected = {
|
|
1308
|
+
match,
|
|
1309
|
+
fromTerminator: true
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
if (selected != null) return commitLongestMatch(context, selected.match, selected.fromTerminator ? void 0 : optionsTerminatorMatches[0].result);
|
|
1313
|
+
return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorMatches[0].result);
|
|
1314
|
+
};
|
|
1315
|
+
const parseSyncBranches = (context) => {
|
|
1225
1316
|
let bestMatch = null;
|
|
1317
|
+
const optionsTerminatorMatches = [];
|
|
1226
1318
|
let error = getInitialError(context);
|
|
1227
1319
|
const activeState = normalizeExclusiveState(context.state);
|
|
1228
1320
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
1229
1321
|
const parser = syncParsers[i];
|
|
1230
|
-
const
|
|
1322
|
+
const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
|
|
1323
|
+
const result = parser.parse(childContext);
|
|
1324
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
1325
|
+
optionsTerminatorMatches.push({
|
|
1326
|
+
index: i,
|
|
1327
|
+
result,
|
|
1328
|
+
consumed: 1,
|
|
1329
|
+
...normalizeExclusiveState(result.next.state) != null ? { selectedAfterTerminator: true } : {}
|
|
1330
|
+
});
|
|
1331
|
+
continue;
|
|
1332
|
+
}
|
|
1231
1333
|
if (result.success) {
|
|
1232
1334
|
const consumed = context.buffer.length - result.next.buffer.length;
|
|
1233
1335
|
const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
|
|
1234
1336
|
if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
|
|
1235
1337
|
index: i,
|
|
1236
|
-
parser,
|
|
1237
1338
|
result,
|
|
1238
1339
|
consumed
|
|
1239
1340
|
};
|
|
1240
1341
|
} else if (error.consumed < result.consumed) error = result;
|
|
1241
1342
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
success: true,
|
|
1246
|
-
next: {
|
|
1247
|
-
...context,
|
|
1248
|
-
buffer: bestMatch.result.next.buffer,
|
|
1249
|
-
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
1250
|
-
state: createExclusiveState(context.state, bestMatch.index, bestMatch.parser, bestMatch.result),
|
|
1251
|
-
...mergedExec != null ? {
|
|
1252
|
-
exec: mergedExec,
|
|
1253
|
-
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1254
|
-
} : {}
|
|
1255
|
-
},
|
|
1256
|
-
consumed: bestMatch.result.consumed
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1343
|
+
const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
|
|
1344
|
+
if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
|
|
1345
|
+
if (bestMatch != null) return commitLongestMatch(context, bestMatch);
|
|
1259
1346
|
return {
|
|
1260
1347
|
...error,
|
|
1261
1348
|
success: false
|
|
1262
1349
|
};
|
|
1263
1350
|
};
|
|
1264
|
-
const
|
|
1351
|
+
const parseAsyncBranches = async (context) => {
|
|
1265
1352
|
let bestMatch = null;
|
|
1353
|
+
const optionsTerminatorMatches = [];
|
|
1266
1354
|
let error = getInitialError(context);
|
|
1267
1355
|
const activeState = normalizeExclusiveState(context.state);
|
|
1268
1356
|
for (let i = 0; i < parsers.length; i++) {
|
|
1269
1357
|
const parser = parsers[i];
|
|
1270
|
-
const
|
|
1358
|
+
const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
|
|
1359
|
+
const resultOrPromise = parser.parse(childContext);
|
|
1271
1360
|
const result = await resultOrPromise;
|
|
1361
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
1362
|
+
optionsTerminatorMatches.push({
|
|
1363
|
+
index: i,
|
|
1364
|
+
result,
|
|
1365
|
+
consumed: 1,
|
|
1366
|
+
...normalizeExclusiveState(result.next.state) != null ? { selectedAfterTerminator: true } : {}
|
|
1367
|
+
});
|
|
1368
|
+
continue;
|
|
1369
|
+
}
|
|
1272
1370
|
if (result.success) {
|
|
1273
1371
|
const consumed = context.buffer.length - result.next.buffer.length;
|
|
1274
1372
|
const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
|
|
1275
1373
|
if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
|
|
1276
1374
|
index: i,
|
|
1277
|
-
parser,
|
|
1278
1375
|
result,
|
|
1279
1376
|
consumed
|
|
1280
1377
|
};
|
|
1281
1378
|
} else if (error.consumed < result.consumed) error = result;
|
|
1282
1379
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
success: true,
|
|
1287
|
-
next: {
|
|
1288
|
-
...context,
|
|
1289
|
-
buffer: bestMatch.result.next.buffer,
|
|
1290
|
-
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
1291
|
-
state: createExclusiveState(context.state, bestMatch.index, bestMatch.parser, bestMatch.result),
|
|
1292
|
-
...mergedExec != null ? {
|
|
1293
|
-
exec: mergedExec,
|
|
1294
|
-
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1295
|
-
} : {}
|
|
1296
|
-
},
|
|
1297
|
-
consumed: bestMatch.result.consumed
|
|
1298
|
-
};
|
|
1299
|
-
}
|
|
1380
|
+
const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
|
|
1381
|
+
if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
|
|
1382
|
+
if (bestMatch != null) return commitLongestMatch(context, bestMatch);
|
|
1300
1383
|
return {
|
|
1301
1384
|
...error,
|
|
1302
1385
|
success: false
|
|
@@ -1319,7 +1402,7 @@ function longestMatch(...args) {
|
|
|
1319
1402
|
return extractExclusivePhase2Seed(parsers, state, exec, combinedMode);
|
|
1320
1403
|
},
|
|
1321
1404
|
parse(context) {
|
|
1322
|
-
return require_mode_dispatch.dispatchByMode(combinedMode, () =>
|
|
1405
|
+
return require_mode_dispatch.dispatchByMode(combinedMode, () => parseSyncBranches(context), () => parseAsyncBranches(context));
|
|
1323
1406
|
},
|
|
1324
1407
|
getSuggestRuntimeNodes(state, path) {
|
|
1325
1408
|
return getExclusiveSuggestRuntimeNodes(parsers, state, path);
|
package/dist/constructs.js
CHANGED
|
@@ -516,6 +516,35 @@ function createExclusiveState(parentState, index, parser, result) {
|
|
|
516
516
|
return annotateFreshArray(parentState, [index, annotatedResult]);
|
|
517
517
|
}
|
|
518
518
|
/**
|
|
519
|
+
* Detects a branch result that handled only the global options terminator.
|
|
520
|
+
* Such a result advances the shared parser context, but does not identify
|
|
521
|
+
* which exclusive branch matched.
|
|
522
|
+
* @internal
|
|
523
|
+
*/
|
|
524
|
+
function isOptionsTerminatorOnlyResult(context, result) {
|
|
525
|
+
return !context.optionsTerminated && context.buffer[0] === "--" && result.success && result.next.optionsTerminated && result.consumed.length === 1 && result.consumed[0] === "--";
|
|
526
|
+
}
|
|
527
|
+
function isUnselectedBooleanOptionState(state) {
|
|
528
|
+
return state != null && typeof state === "object" && "success" in state && state.success === true && "value" in state && state.value === false;
|
|
529
|
+
}
|
|
530
|
+
function preserveExclusiveStateAfterOptionsTerminator(context, result) {
|
|
531
|
+
const mergedExec = mergeChildExec(context.exec, result.next.exec);
|
|
532
|
+
return {
|
|
533
|
+
success: true,
|
|
534
|
+
next: {
|
|
535
|
+
...context,
|
|
536
|
+
buffer: result.next.buffer,
|
|
537
|
+
optionsTerminated: true,
|
|
538
|
+
state: context.state,
|
|
539
|
+
...mergedExec != null ? {
|
|
540
|
+
exec: mergedExec,
|
|
541
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
542
|
+
} : {}
|
|
543
|
+
},
|
|
544
|
+
consumed: result.consumed
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
519
548
|
* Creates a complete() method shared by or() and longestMatch().
|
|
520
549
|
* @internal
|
|
521
550
|
*/
|
|
@@ -752,9 +781,15 @@ function or(...args) {
|
|
|
752
781
|
let zeroConsumedBranch = null;
|
|
753
782
|
let zeroConsumedCount = 0;
|
|
754
783
|
let provisionalConsuming = null;
|
|
784
|
+
let optionsTerminatorResult = null;
|
|
755
785
|
let provisionalAmbiguous = false;
|
|
756
786
|
for (const [parser, i] of orderedParsers) {
|
|
757
787
|
const result = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
|
|
788
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
789
|
+
if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
|
|
790
|
+
optionsTerminatorResult ??= result;
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
758
793
|
if (result.success && result.consumed.length > 0) {
|
|
759
794
|
if (result.provisional) {
|
|
760
795
|
const activeBranchLocked = activeState != null && activeState[1].success && activeState[1].consumed.length > 0;
|
|
@@ -935,6 +970,7 @@ function or(...args) {
|
|
|
935
970
|
}
|
|
936
971
|
}
|
|
937
972
|
}
|
|
973
|
+
if (optionsTerminatorResult != null) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorResult);
|
|
938
974
|
return {
|
|
939
975
|
...error,
|
|
940
976
|
success: false
|
|
@@ -948,10 +984,16 @@ function or(...args) {
|
|
|
948
984
|
let zeroConsumedBranch = null;
|
|
949
985
|
let zeroConsumedCount = 0;
|
|
950
986
|
let provisionalConsuming = null;
|
|
987
|
+
let optionsTerminatorResult = null;
|
|
951
988
|
let provisionalAmbiguous = false;
|
|
952
989
|
for (const [parser, i] of orderedParsers) {
|
|
953
990
|
const resultOrPromise = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
|
|
954
991
|
const result = await resultOrPromise;
|
|
992
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
993
|
+
if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
|
|
994
|
+
optionsTerminatorResult ??= result;
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
955
997
|
if (result.success && result.consumed.length > 0) {
|
|
956
998
|
if (result.provisional) {
|
|
957
999
|
const activeBranchLocked = activeState != null && activeState[1].success && activeState[1].consumed.length > 0;
|
|
@@ -1134,6 +1176,7 @@ function or(...args) {
|
|
|
1134
1176
|
}
|
|
1135
1177
|
}
|
|
1136
1178
|
}
|
|
1179
|
+
if (optionsTerminatorResult != null) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorResult);
|
|
1137
1180
|
return {
|
|
1138
1181
|
...error,
|
|
1139
1182
|
success: false
|
|
@@ -1221,82 +1264,122 @@ function longestMatch(...args) {
|
|
|
1221
1264
|
return createUnexpectedInputErrorWithScopedSuggestions(defaultMsg, token, parsers, options?.errors?.suggestions);
|
|
1222
1265
|
})()
|
|
1223
1266
|
});
|
|
1224
|
-
const
|
|
1267
|
+
const commitLongestMatch = (context, match, optionsTerminatorResult) => {
|
|
1268
|
+
const selectedResult = optionsTerminatorResult == null ? match.result : {
|
|
1269
|
+
...match.result,
|
|
1270
|
+
next: {
|
|
1271
|
+
...match.result.next,
|
|
1272
|
+
buffer: optionsTerminatorResult.next.buffer,
|
|
1273
|
+
optionsTerminated: true
|
|
1274
|
+
},
|
|
1275
|
+
consumed: [...optionsTerminatorResult.consumed, ...match.result.consumed]
|
|
1276
|
+
};
|
|
1277
|
+
const parser = parsers[match.index];
|
|
1278
|
+
const mergedExec = mergeChildExec(context.exec, selectedResult.next.exec);
|
|
1279
|
+
return {
|
|
1280
|
+
success: true,
|
|
1281
|
+
next: {
|
|
1282
|
+
...context,
|
|
1283
|
+
buffer: selectedResult.next.buffer,
|
|
1284
|
+
optionsTerminated: selectedResult.next.optionsTerminated,
|
|
1285
|
+
state: createExclusiveState(context.state, match.index, parser, selectedResult),
|
|
1286
|
+
...mergedExec != null ? {
|
|
1287
|
+
exec: mergedExec,
|
|
1288
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1289
|
+
} : {}
|
|
1290
|
+
},
|
|
1291
|
+
consumed: selectedResult.consumed
|
|
1292
|
+
};
|
|
1293
|
+
};
|
|
1294
|
+
const resolveLongestMatchOptionsTerminator = (context, bestMatch, optionsTerminatorMatches) => {
|
|
1295
|
+
if (optionsTerminatorMatches.length < 1) return null;
|
|
1296
|
+
if (bestMatch != null && bestMatch.consumed > 0) return null;
|
|
1297
|
+
const activeState = normalizeExclusiveState(context.state);
|
|
1298
|
+
if (activeState != null && activeState[1].success && activeState[1].consumed.length > 0) return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorMatches[0].result);
|
|
1299
|
+
let selected = bestMatch == null ? null : {
|
|
1300
|
+
match: bestMatch,
|
|
1301
|
+
fromTerminator: false
|
|
1302
|
+
};
|
|
1303
|
+
for (const match of optionsTerminatorMatches) {
|
|
1304
|
+
if (!match.selectedAfterTerminator && (extractRequiredUsage(parsers[match.index].usage).length > 0 || isUnselectedBooleanOptionState(match.result.next.state))) continue;
|
|
1305
|
+
const selectedIsProvisional = selected != null && !!selected.match.result.provisional;
|
|
1306
|
+
const matchIsProvisional = !!match.result.provisional;
|
|
1307
|
+
if (selected == null || selectedIsProvisional && !matchIsProvisional || selectedIsProvisional === matchIsProvisional && match.index < selected.match.index) selected = {
|
|
1308
|
+
match,
|
|
1309
|
+
fromTerminator: true
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
if (selected != null) return commitLongestMatch(context, selected.match, selected.fromTerminator ? void 0 : optionsTerminatorMatches[0].result);
|
|
1313
|
+
return preserveExclusiveStateAfterOptionsTerminator(context, optionsTerminatorMatches[0].result);
|
|
1314
|
+
};
|
|
1315
|
+
const parseSyncBranches = (context) => {
|
|
1225
1316
|
let bestMatch = null;
|
|
1317
|
+
const optionsTerminatorMatches = [];
|
|
1226
1318
|
let error = getInitialError(context);
|
|
1227
1319
|
const activeState = normalizeExclusiveState(context.state);
|
|
1228
1320
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
1229
1321
|
const parser = syncParsers[i];
|
|
1230
|
-
const
|
|
1322
|
+
const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
|
|
1323
|
+
const result = parser.parse(childContext);
|
|
1324
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
1325
|
+
optionsTerminatorMatches.push({
|
|
1326
|
+
index: i,
|
|
1327
|
+
result,
|
|
1328
|
+
consumed: 1,
|
|
1329
|
+
...normalizeExclusiveState(result.next.state) != null ? { selectedAfterTerminator: true } : {}
|
|
1330
|
+
});
|
|
1331
|
+
continue;
|
|
1332
|
+
}
|
|
1231
1333
|
if (result.success) {
|
|
1232
1334
|
const consumed = context.buffer.length - result.next.buffer.length;
|
|
1233
1335
|
const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
|
|
1234
1336
|
if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
|
|
1235
1337
|
index: i,
|
|
1236
|
-
parser,
|
|
1237
1338
|
result,
|
|
1238
1339
|
consumed
|
|
1239
1340
|
};
|
|
1240
1341
|
} else if (error.consumed < result.consumed) error = result;
|
|
1241
1342
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
success: true,
|
|
1246
|
-
next: {
|
|
1247
|
-
...context,
|
|
1248
|
-
buffer: bestMatch.result.next.buffer,
|
|
1249
|
-
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
1250
|
-
state: createExclusiveState(context.state, bestMatch.index, bestMatch.parser, bestMatch.result),
|
|
1251
|
-
...mergedExec != null ? {
|
|
1252
|
-
exec: mergedExec,
|
|
1253
|
-
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1254
|
-
} : {}
|
|
1255
|
-
},
|
|
1256
|
-
consumed: bestMatch.result.consumed
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1343
|
+
const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
|
|
1344
|
+
if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
|
|
1345
|
+
if (bestMatch != null) return commitLongestMatch(context, bestMatch);
|
|
1259
1346
|
return {
|
|
1260
1347
|
...error,
|
|
1261
1348
|
success: false
|
|
1262
1349
|
};
|
|
1263
1350
|
};
|
|
1264
|
-
const
|
|
1351
|
+
const parseAsyncBranches = async (context) => {
|
|
1265
1352
|
let bestMatch = null;
|
|
1353
|
+
const optionsTerminatorMatches = [];
|
|
1266
1354
|
let error = getInitialError(context);
|
|
1267
1355
|
const activeState = normalizeExclusiveState(context.state);
|
|
1268
1356
|
for (let i = 0; i < parsers.length; i++) {
|
|
1269
1357
|
const parser = parsers[i];
|
|
1270
|
-
const
|
|
1358
|
+
const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
|
|
1359
|
+
const resultOrPromise = parser.parse(childContext);
|
|
1271
1360
|
const result = await resultOrPromise;
|
|
1361
|
+
if (isOptionsTerminatorOnlyResult(context, result)) {
|
|
1362
|
+
optionsTerminatorMatches.push({
|
|
1363
|
+
index: i,
|
|
1364
|
+
result,
|
|
1365
|
+
consumed: 1,
|
|
1366
|
+
...normalizeExclusiveState(result.next.state) != null ? { selectedAfterTerminator: true } : {}
|
|
1367
|
+
});
|
|
1368
|
+
continue;
|
|
1369
|
+
}
|
|
1272
1370
|
if (result.success) {
|
|
1273
1371
|
const consumed = context.buffer.length - result.next.buffer.length;
|
|
1274
1372
|
const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
|
|
1275
1373
|
if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
|
|
1276
1374
|
index: i,
|
|
1277
|
-
parser,
|
|
1278
1375
|
result,
|
|
1279
1376
|
consumed
|
|
1280
1377
|
};
|
|
1281
1378
|
} else if (error.consumed < result.consumed) error = result;
|
|
1282
1379
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
success: true,
|
|
1287
|
-
next: {
|
|
1288
|
-
...context,
|
|
1289
|
-
buffer: bestMatch.result.next.buffer,
|
|
1290
|
-
optionsTerminated: bestMatch.result.next.optionsTerminated,
|
|
1291
|
-
state: createExclusiveState(context.state, bestMatch.index, bestMatch.parser, bestMatch.result),
|
|
1292
|
-
...mergedExec != null ? {
|
|
1293
|
-
exec: mergedExec,
|
|
1294
|
-
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1295
|
-
} : {}
|
|
1296
|
-
},
|
|
1297
|
-
consumed: bestMatch.result.consumed
|
|
1298
|
-
};
|
|
1299
|
-
}
|
|
1380
|
+
const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
|
|
1381
|
+
if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
|
|
1382
|
+
if (bestMatch != null) return commitLongestMatch(context, bestMatch);
|
|
1300
1383
|
return {
|
|
1301
1384
|
...error,
|
|
1302
1385
|
success: false
|
|
@@ -1319,7 +1402,7 @@ function longestMatch(...args) {
|
|
|
1319
1402
|
return extractExclusivePhase2Seed(parsers, state, exec, combinedMode);
|
|
1320
1403
|
},
|
|
1321
1404
|
parse(context) {
|
|
1322
|
-
return dispatchByMode(combinedMode, () =>
|
|
1405
|
+
return dispatchByMode(combinedMode, () => parseSyncBranches(context), () => parseAsyncBranches(context));
|
|
1323
1406
|
},
|
|
1324
1407
|
getSuggestRuntimeNodes(state, path) {
|
|
1325
1408
|
return getExclusiveSuggestRuntimeNodes(parsers, state, path);
|
package/dist/primitives.cjs
CHANGED
|
@@ -237,7 +237,7 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry,
|
|
|
237
237
|
* Internal sync helper for option suggest functionality.
|
|
238
238
|
* @internal
|
|
239
239
|
*/
|
|
240
|
-
function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
240
|
+
function* suggestOptionSync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
241
241
|
if (hidden) return;
|
|
242
242
|
const equalsIndex = prefix.indexOf("=");
|
|
243
243
|
if (equalsIndex >= 0) {
|
|
@@ -265,7 +265,8 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
|
|
|
265
265
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
266
266
|
yield {
|
|
267
267
|
kind: "literal",
|
|
268
|
-
text: optionName$1
|
|
268
|
+
text: optionName$1,
|
|
269
|
+
...description && { description }
|
|
269
270
|
};
|
|
270
271
|
}
|
|
271
272
|
}
|
|
@@ -321,7 +322,7 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
|
|
|
321
322
|
* Internal async helper for option suggest functionality.
|
|
322
323
|
* @internal
|
|
323
324
|
*/
|
|
324
|
-
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
325
|
+
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
325
326
|
if (hidden) return;
|
|
326
327
|
const equalsIndex = prefix.indexOf("=");
|
|
327
328
|
if (equalsIndex >= 0) {
|
|
@@ -349,7 +350,8 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
|
|
|
349
350
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
350
351
|
yield {
|
|
351
352
|
kind: "literal",
|
|
352
|
-
text: optionName$1
|
|
353
|
+
text: optionName$1,
|
|
354
|
+
...description && { description }
|
|
353
355
|
};
|
|
354
356
|
}
|
|
355
357
|
}
|
|
@@ -615,8 +617,8 @@ function option(...args) {
|
|
|
615
617
|
return require_mode_dispatch.dispatchByMode(mode, completeSync, completeAsync);
|
|
616
618
|
},
|
|
617
619
|
suggest(context, prefix) {
|
|
618
|
-
if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), context, prefix);
|
|
619
|
-
return suggestOptionSync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), context, prefix);
|
|
620
|
+
if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), options.description, context, prefix);
|
|
621
|
+
return suggestOptionSync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), options.description, context, prefix);
|
|
620
622
|
},
|
|
621
623
|
getDocFragments(_state, defaultValue) {
|
|
622
624
|
if (require_usage.isDocHidden(options.hidden)) return {
|
|
@@ -893,7 +895,8 @@ function flag(...args) {
|
|
|
893
895
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
894
896
|
suggestions.push({
|
|
895
897
|
kind: "literal",
|
|
896
|
-
text: optionName$1
|
|
898
|
+
text: optionName$1,
|
|
899
|
+
...options.description && { description: options.description }
|
|
897
900
|
});
|
|
898
901
|
}
|
|
899
902
|
}
|
|
@@ -1157,11 +1160,14 @@ function* suggestCommandSync(context, prefix, name, parser, options) {
|
|
|
1157
1160
|
if (require_usage.isSuggestionHidden(options.hidden)) return;
|
|
1158
1161
|
const state = normalizeCommandState(context.state);
|
|
1159
1162
|
if (state === void 0) {
|
|
1160
|
-
if (name.startsWith(prefix))
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1163
|
+
if (name.startsWith(prefix)) {
|
|
1164
|
+
const description = options.brief ?? options.description;
|
|
1165
|
+
yield {
|
|
1166
|
+
kind: "literal",
|
|
1167
|
+
text: name,
|
|
1168
|
+
...description && { description }
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1165
1171
|
} else if (state[0] === "matched") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
|
|
1166
1172
|
else if (state[0] === "parsing") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, state[1], parser), parser.usage), prefix);
|
|
1167
1173
|
}
|
|
@@ -1169,11 +1175,14 @@ async function* suggestCommandAsync(context, prefix, name, parser, options) {
|
|
|
1169
1175
|
if (require_usage.isSuggestionHidden(options.hidden)) return;
|
|
1170
1176
|
const state = normalizeCommandState(context.state);
|
|
1171
1177
|
if (state === void 0) {
|
|
1172
|
-
if (name.startsWith(prefix))
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1178
|
+
if (name.startsWith(prefix)) {
|
|
1179
|
+
const description = options.brief ?? options.description;
|
|
1180
|
+
yield {
|
|
1181
|
+
kind: "literal",
|
|
1182
|
+
text: name,
|
|
1183
|
+
...description && { description }
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1177
1186
|
} else if (state[0] === "matched") {
|
|
1178
1187
|
const suggestions = parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
|
|
1179
1188
|
for await (const s of suggestions) yield s;
|
package/dist/primitives.js
CHANGED
|
@@ -237,7 +237,7 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry,
|
|
|
237
237
|
* Internal sync helper for option suggest functionality.
|
|
238
238
|
* @internal
|
|
239
239
|
*/
|
|
240
|
-
function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
240
|
+
function* suggestOptionSync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
241
241
|
if (hidden) return;
|
|
242
242
|
const equalsIndex = prefix.indexOf("=");
|
|
243
243
|
if (equalsIndex >= 0) {
|
|
@@ -265,7 +265,8 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
|
|
|
265
265
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
266
266
|
yield {
|
|
267
267
|
kind: "literal",
|
|
268
|
-
text: optionName$1
|
|
268
|
+
text: optionName$1,
|
|
269
|
+
...description && { description }
|
|
269
270
|
};
|
|
270
271
|
}
|
|
271
272
|
}
|
|
@@ -321,7 +322,7 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
|
|
|
321
322
|
* Internal async helper for option suggest functionality.
|
|
322
323
|
* @internal
|
|
323
324
|
*/
|
|
324
|
-
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context, prefix) {
|
|
325
|
+
async function* suggestOptionAsync(optionNames$1, valueParser, hidden, description, context, prefix) {
|
|
325
326
|
if (hidden) return;
|
|
326
327
|
const equalsIndex = prefix.indexOf("=");
|
|
327
328
|
if (equalsIndex >= 0) {
|
|
@@ -349,7 +350,8 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
|
|
|
349
350
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
350
351
|
yield {
|
|
351
352
|
kind: "literal",
|
|
352
|
-
text: optionName$1
|
|
353
|
+
text: optionName$1,
|
|
354
|
+
...description && { description }
|
|
353
355
|
};
|
|
354
356
|
}
|
|
355
357
|
}
|
|
@@ -615,8 +617,8 @@ function option(...args) {
|
|
|
615
617
|
return dispatchByMode(mode, completeSync, completeAsync);
|
|
616
618
|
},
|
|
617
619
|
suggest(context, prefix) {
|
|
618
|
-
if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, isSuggestionHidden(options.hidden), context, prefix);
|
|
619
|
-
return suggestOptionSync(optionNames$1, valueParser, isSuggestionHidden(options.hidden), context, prefix);
|
|
620
|
+
if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, isSuggestionHidden(options.hidden), options.description, context, prefix);
|
|
621
|
+
return suggestOptionSync(optionNames$1, valueParser, isSuggestionHidden(options.hidden), options.description, context, prefix);
|
|
620
622
|
},
|
|
621
623
|
getDocFragments(_state, defaultValue) {
|
|
622
624
|
if (isDocHidden(options.hidden)) return {
|
|
@@ -893,7 +895,8 @@ function flag(...args) {
|
|
|
893
895
|
if (prefix === "-" && optionName$1.length !== 2) continue;
|
|
894
896
|
suggestions.push({
|
|
895
897
|
kind: "literal",
|
|
896
|
-
text: optionName$1
|
|
898
|
+
text: optionName$1,
|
|
899
|
+
...options.description && { description: options.description }
|
|
897
900
|
});
|
|
898
901
|
}
|
|
899
902
|
}
|
|
@@ -1157,11 +1160,14 @@ function* suggestCommandSync(context, prefix, name, parser, options) {
|
|
|
1157
1160
|
if (isSuggestionHidden(options.hidden)) return;
|
|
1158
1161
|
const state = normalizeCommandState(context.state);
|
|
1159
1162
|
if (state === void 0) {
|
|
1160
|
-
if (name.startsWith(prefix))
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1163
|
+
if (name.startsWith(prefix)) {
|
|
1164
|
+
const description = options.brief ?? options.description;
|
|
1165
|
+
yield {
|
|
1166
|
+
kind: "literal",
|
|
1167
|
+
text: name,
|
|
1168
|
+
...description && { description }
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1165
1171
|
} else if (state[0] === "matched") yield* parser.suggest(withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
|
|
1166
1172
|
else if (state[0] === "parsing") yield* parser.suggest(withChildContext(context, name, getCommandChildState(context.state, state[1], parser), parser.usage), prefix);
|
|
1167
1173
|
}
|
|
@@ -1169,11 +1175,14 @@ async function* suggestCommandAsync(context, prefix, name, parser, options) {
|
|
|
1169
1175
|
if (isSuggestionHidden(options.hidden)) return;
|
|
1170
1176
|
const state = normalizeCommandState(context.state);
|
|
1171
1177
|
if (state === void 0) {
|
|
1172
|
-
if (name.startsWith(prefix))
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1178
|
+
if (name.startsWith(prefix)) {
|
|
1179
|
+
const description = options.brief ?? options.description;
|
|
1180
|
+
yield {
|
|
1181
|
+
kind: "literal",
|
|
1182
|
+
text: name,
|
|
1183
|
+
...description && { description }
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1177
1186
|
} else if (state[0] === "matched") {
|
|
1178
1187
|
const suggestions = parser.suggest(withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
|
|
1179
1188
|
for await (const s of suggestions) yield s;
|