@optique/core 1.4.0-dev.2611 → 1.4.0-dev.2614

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.
@@ -8,12 +8,13 @@ import { createDependencySourceState, dependencyId, isDependencySourceState, isP
8
8
  import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyRuntimeContext, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, getDefaultDependencySnapshot, guaranteedStaticSourceIdsKey, hasInactiveCompletion, isMatchedState, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
9
9
  import { defineInheritedAnnotationParser, defineParseLanes, getOwnParseLanes, getParserSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
10
10
  import { annotationViewTargets, getWrappedChildParseState, getWrappedChildState, reconcileObjectChildState, unwrapAnnotationView } from "./annotation-state.js";
11
+ import { collectLeadingCandidates } from "./usage-internals.js";
12
+ import { adoptOptionScope, combinedOptionScope, conditionalOptionScope, forkOptionScope, restoreOptionScope, scopeParser, selectableOptionScope, withOptionScope, withParserOptionScope } from "./short-option.js";
11
13
  import { allowDuplicateLeadingCommandNamesKey } from "./internal/command-alias.js";
12
14
  import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
13
15
  import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
14
16
  import { fluent } from "./modifiers.js";
15
17
  import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar } from "./suggestion.js";
16
- import { collectLeadingCandidates } from "./usage-internals.js";
17
18
 
18
19
  //#region src/constructs.ts
19
20
  /**
@@ -48,7 +49,8 @@ function withoutRepublishInstruction(exec) {
48
49
  }
49
50
  function withChildContext$1(context, segment, state, parser, usage) {
50
51
  const childState = parser == null ? state : getWrappedChildParseState(context.state, state, parser);
51
- return withChildContext(context, segment, childState, usage);
52
+ const child = withChildContext(context, segment, childState, usage);
53
+ return parser == null ? child : withParserOptionScope(child, parser);
52
54
  }
53
55
  function isUnmatchedDependencyState(state, parser) {
54
56
  if (state === void 0) return true;
@@ -1402,7 +1404,7 @@ function or(...args) {
1402
1404
  let optionsTerminatorResult = null;
1403
1405
  let provisionalAmbiguous = false;
1404
1406
  for (const [parser, i] of orderedParsers) {
1405
- const result = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
1407
+ const result = parser.parse(withChildContext$1(forkOptionScope(context), i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
1406
1408
  if (isOptionsTerminatorOnlyResult(context, result)) {
1407
1409
  if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
1408
1410
  optionsTerminatorResult ??= result;
@@ -1437,7 +1439,7 @@ function or(...args) {
1437
1439
  return {
1438
1440
  success: true,
1439
1441
  next: {
1440
- ...context,
1442
+ ...adoptOptionScope(context, result.next),
1441
1443
  buffer: result.next.buffer,
1442
1444
  optionsTerminated: result.next.optionsTerminated,
1443
1445
  state: createExclusiveState(context.state, i, parser, result),
@@ -1473,7 +1475,7 @@ function or(...args) {
1473
1475
  return {
1474
1476
  success: true,
1475
1477
  next: {
1476
- ...context,
1478
+ ...adoptOptionScope(context, replayedResult.next),
1477
1479
  buffer: replayedResult.next.buffer,
1478
1480
  optionsTerminated: replayedResult.next.optionsTerminated,
1479
1481
  state: createExclusiveState(context.state, i, parser, {
@@ -1492,7 +1494,7 @@ function or(...args) {
1492
1494
  return {
1493
1495
  success: true,
1494
1496
  next: {
1495
- ...context,
1497
+ ...adoptOptionScope(context, result.next),
1496
1498
  buffer: result.next.buffer,
1497
1499
  optionsTerminated: result.next.optionsTerminated,
1498
1500
  state: createExclusiveState(context.state, i, parser, result),
@@ -1518,7 +1520,7 @@ function or(...args) {
1518
1520
  success: true,
1519
1521
  ...zeroConsumedBranch.result.provisional ? { provisional: true } : {},
1520
1522
  next: {
1521
- ...context,
1523
+ ...adoptOptionScope(context, zeroConsumedBranch.result.next),
1522
1524
  state: createExclusiveState(context.state, zeroConsumedBranch.index, zeroConsumedBranch.parser, zeroConsumedBranch.result),
1523
1525
  ...mergedExec != null ? {
1524
1526
  exec: mergedExec,
@@ -1536,7 +1538,7 @@ function or(...args) {
1536
1538
  success: true,
1537
1539
  provisional: true,
1538
1540
  next: {
1539
- ...context,
1541
+ ...adoptOptionScope(context, provisionalConsuming.result.next),
1540
1542
  buffer: provisionalConsuming.result.next.buffer,
1541
1543
  optionsTerminated: provisionalConsuming.result.next.optionsTerminated,
1542
1544
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, provisionalConsuming.result),
@@ -1551,7 +1553,7 @@ function or(...args) {
1551
1553
  if (activeState != null && activeState[1].success) {
1552
1554
  const previouslyConsumed = activeState[1].consumed;
1553
1555
  const checkResult = provisionalConsuming.parser.parse({
1554
- ...withChildContext$1(context, provisionalConsuming.index, provisionalConsuming.parser.initialState, provisionalConsuming.parser),
1556
+ ...withChildContext$1(forkOptionScope(context), provisionalConsuming.index, provisionalConsuming.parser.initialState, provisionalConsuming.parser),
1555
1557
  buffer: previouslyConsumed
1556
1558
  });
1557
1559
  const canConsumeShared = checkResult.success && checkResult.consumed.length === previouslyConsumed.length && checkResult.consumed.every((c, idx) => c === previouslyConsumed[idx]);
@@ -1570,7 +1572,7 @@ function or(...args) {
1570
1572
  success: true,
1571
1573
  provisional: true,
1572
1574
  next: {
1573
- ...context,
1575
+ ...adoptOptionScope(context, replayedResult.next),
1574
1576
  buffer: replayedResult.next.buffer,
1575
1577
  optionsTerminated: replayedResult.next.optionsTerminated,
1576
1578
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
@@ -1605,7 +1607,7 @@ function or(...args) {
1605
1607
  let optionsTerminatorResult = null;
1606
1608
  let provisionalAmbiguous = false;
1607
1609
  for (const [parser, i] of orderedParsers) {
1608
- const resultOrPromise = parser.parse(withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
1610
+ const resultOrPromise = parser.parse(withChildContext$1(forkOptionScope(context), i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser));
1609
1611
  const result = await resultOrPromise;
1610
1612
  if (isOptionsTerminatorOnlyResult(context, result)) {
1611
1613
  if (activeState?.[0] === i && activeState[1].success && activeState[1].consumed.length > 0 && result.next.buffer.length < 1) return preserveExclusiveStateAfterOptionsTerminator(context, result);
@@ -1641,7 +1643,7 @@ function or(...args) {
1641
1643
  return {
1642
1644
  success: true,
1643
1645
  next: {
1644
- ...context,
1646
+ ...adoptOptionScope(context, result.next),
1645
1647
  buffer: result.next.buffer,
1646
1648
  optionsTerminated: result.next.optionsTerminated,
1647
1649
  state: createExclusiveState(context.state, i, parser, result),
@@ -1679,7 +1681,7 @@ function or(...args) {
1679
1681
  return {
1680
1682
  success: true,
1681
1683
  next: {
1682
- ...context,
1684
+ ...adoptOptionScope(context, replayedResult.next),
1683
1685
  buffer: replayedResult.next.buffer,
1684
1686
  optionsTerminated: replayedResult.next.optionsTerminated,
1685
1687
  state: createExclusiveState(context.state, i, parser, {
@@ -1698,7 +1700,7 @@ function or(...args) {
1698
1700
  return {
1699
1701
  success: true,
1700
1702
  next: {
1701
- ...context,
1703
+ ...adoptOptionScope(context, result.next),
1702
1704
  buffer: result.next.buffer,
1703
1705
  optionsTerminated: result.next.optionsTerminated,
1704
1706
  state: createExclusiveState(context.state, i, parser, result),
@@ -1724,7 +1726,7 @@ function or(...args) {
1724
1726
  success: true,
1725
1727
  ...zeroConsumedBranch.result.provisional ? { provisional: true } : {},
1726
1728
  next: {
1727
- ...context,
1729
+ ...adoptOptionScope(context, zeroConsumedBranch.result.next),
1728
1730
  state: createExclusiveState(context.state, zeroConsumedBranch.index, zeroConsumedBranch.parser, zeroConsumedBranch.result),
1729
1731
  ...mergedExec != null ? {
1730
1732
  exec: mergedExec,
@@ -1742,7 +1744,7 @@ function or(...args) {
1742
1744
  success: true,
1743
1745
  provisional: true,
1744
1746
  next: {
1745
- ...context,
1747
+ ...adoptOptionScope(context, provisionalConsuming.result.next),
1746
1748
  buffer: provisionalConsuming.result.next.buffer,
1747
1749
  optionsTerminated: provisionalConsuming.result.next.optionsTerminated,
1748
1750
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, provisionalConsuming.result),
@@ -1757,7 +1759,7 @@ function or(...args) {
1757
1759
  if (activeState != null && activeState[1].success) {
1758
1760
  const previouslyConsumed = activeState[1].consumed;
1759
1761
  const checkResult = await provisionalConsuming.parser.parse({
1760
- ...withChildContext$1(context, provisionalConsuming.index, provisionalConsuming.parser.initialState, provisionalConsuming.parser),
1762
+ ...withChildContext$1(forkOptionScope(context), provisionalConsuming.index, provisionalConsuming.parser.initialState, provisionalConsuming.parser),
1761
1763
  buffer: previouslyConsumed
1762
1764
  });
1763
1765
  const canConsumeShared = checkResult.success && checkResult.consumed.length === previouslyConsumed.length && checkResult.consumed.every((c, idx) => c === previouslyConsumed[idx]);
@@ -1776,7 +1778,7 @@ function or(...args) {
1776
1778
  success: true,
1777
1779
  provisional: true,
1778
1780
  next: {
1779
- ...context,
1781
+ ...adoptOptionScope(context, replayedResult.next),
1780
1782
  buffer: replayedResult.next.buffer,
1781
1783
  optionsTerminated: replayedResult.next.optionsTerminated,
1782
1784
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
@@ -1863,7 +1865,7 @@ function or(...args) {
1863
1865
  if (singleDependencyMetadata != null) singleResult.dependencyMetadata = singleDependencyMetadata;
1864
1866
  defineExclusiveSchedulingNodes(singleResult, parsers);
1865
1867
  defineInheritedAnnotationParser(singleResult);
1866
- return fluent(singleResult);
1868
+ return fluent(scopeParser(singleResult, combinedOptionScope(parsers, parsers.map((_, index) => index))));
1867
1869
  }
1868
1870
  /**
1869
1871
  * @since 0.5.0
@@ -1912,7 +1914,7 @@ function createLongestMatch(...args) {
1912
1914
  return {
1913
1915
  success: true,
1914
1916
  next: {
1915
- ...context,
1917
+ ...adoptOptionScope(context, selectedResult.next),
1916
1918
  buffer: selectedResult.next.buffer,
1917
1919
  optionsTerminated: selectedResult.next.optionsTerminated,
1918
1920
  state: createExclusiveState(context.state, match.index, parser, selectedResult),
@@ -1952,7 +1954,7 @@ function createLongestMatch(...args) {
1952
1954
  const activeState = normalizeExclusiveState(context.state);
1953
1955
  for (let i = 0; i < syncParsers.length; i++) {
1954
1956
  const parser = syncParsers[i];
1955
- const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
1957
+ const childContext = withChildContext$1(forkOptionScope(context), i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
1956
1958
  const result = parser.parse(childContext);
1957
1959
  if (isOptionsTerminatorOnlyResult(context, result)) {
1958
1960
  optionsTerminatorMatches.push({
@@ -1988,7 +1990,7 @@ function createLongestMatch(...args) {
1988
1990
  const activeState = normalizeExclusiveState(context.state);
1989
1991
  for (let i = 0; i < parsers.length; i++) {
1990
1992
  const parser = parsers[i];
1991
- const childContext = withChildContext$1(context, i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
1993
+ const childContext = withChildContext$1(forkOptionScope(context), i, activeState == null || activeState[0] !== i || !activeState[1].success ? parser.initialState : activeState[1].next.state, parser);
1992
1994
  const resultOrPromise = parser.parse(childContext);
1993
1995
  const result = await resultOrPromise;
1994
1996
  if (isOptionsTerminatorOnlyResult(context, result)) {
@@ -2079,7 +2081,7 @@ function createLongestMatch(...args) {
2079
2081
  if (multiDependencyMetadata != null) multiResult.dependencyMetadata = multiDependencyMetadata;
2080
2082
  defineExclusiveSchedulingNodes(multiResult, parsers);
2081
2083
  defineInheritedAnnotationParser(multiResult);
2082
- return fluent(multiResult);
2084
+ return fluent(scopeParser(multiResult, combinedOptionScope(parsers, parsers.map((_, index) => index))));
2083
2085
  }
2084
2086
  /**
2085
2087
  * Creates the initial parse error shared by object-like combinators.
@@ -2522,6 +2524,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2522
2524
  next: context,
2523
2525
  consumed: []
2524
2526
  };
2527
+ adoptOptionScope(context, result.next);
2525
2528
  const mergedExec = mergeChildExec(context.exec, result.next.exec);
2526
2529
  const nextState = result.next.state === fieldState ? context.state : {
2527
2530
  ...context.state,
@@ -2553,10 +2556,10 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2553
2556
  parse(context) {
2554
2557
  const fieldState = createFieldStateGetter(context.state, getObjectParseChildState)(field, parser);
2555
2558
  return dispatchByMode(combinedMode, () => {
2556
- const result = parser.parse(withChildContext$1(context, field, fieldState, parser));
2559
+ const result = parser.parse(withChildContext$1(forkOptionScope(context), field, fieldState, parser));
2557
2560
  return adaptFieldLaneResult(context, field, parser, fieldState, result);
2558
2561
  }, async () => {
2559
- const result = await parser.parse(withChildContext$1(context, field, fieldState, parser));
2562
+ const result = await parser.parse(withChildContext$1(forkOptionScope(context), field, fieldState, parser));
2560
2563
  return adaptFieldLaneResult(context, field, parser, fieldState, result);
2561
2564
  });
2562
2565
  }
@@ -2572,8 +2575,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2572
2575
  madeProgress = false;
2573
2576
  const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
2574
2577
  for (const [field, parser] of parserPairs) {
2575
- const result = parser.parse(withChildContext$1(currentContext, field, getFieldState(field, parser), parser));
2578
+ const result = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser));
2576
2579
  if (result.success && result.consumed.length > 0) {
2580
+ adoptOptionScope(currentContext, result.next);
2577
2581
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2578
2582
  currentContext = {
2579
2583
  ...currentContext,
@@ -2604,8 +2608,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2604
2608
  const typedParser = parser;
2605
2609
  if (parser.leadingNames.size > 0 || typedParser.acceptingAnyToken) continue;
2606
2610
  const fieldState = getFieldState(field, parser);
2607
- const result = typedParser.parse(withChildContext$1(currentContext, field, fieldState, parser));
2611
+ const result = typedParser.parse(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser));
2608
2612
  if (result.success && result.consumed.length === 0 && result.next.state !== fieldState) {
2613
+ adoptOptionScope(currentContext, result.next);
2609
2614
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2610
2615
  currentContext = {
2611
2616
  ...currentContext,
@@ -2678,9 +2683,10 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2678
2683
  madeProgress = false;
2679
2684
  const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
2680
2685
  for (const [field, parser] of parserPairs) {
2681
- const resultOrPromise = parser.parse(withChildContext$1(currentContext, field, getFieldState(field, parser), parser));
2686
+ const resultOrPromise = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser));
2682
2687
  const result = await resultOrPromise;
2683
2688
  if (result.success && result.consumed.length > 0) {
2689
+ adoptOptionScope(currentContext, result.next);
2684
2690
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2685
2691
  currentContext = {
2686
2692
  ...currentContext,
@@ -2710,9 +2716,10 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2710
2716
  if (consumedFields.has(field)) continue;
2711
2717
  if (parser.leadingNames.size > 0 || parser.acceptingAnyToken) continue;
2712
2718
  const fieldState = getFieldState(field, parser);
2713
- const resultOrPromise = parser.parse(withChildContext$1(currentContext, field, fieldState, parser));
2719
+ const resultOrPromise = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser));
2714
2720
  const result = await resultOrPromise;
2715
2721
  if (result.success && result.consumed.length === 0 && result.next.state !== fieldState) {
2722
+ adoptOptionScope(currentContext, result.next);
2716
2723
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2717
2724
  currentContext = {
2718
2725
  ...currentContext,
@@ -3093,15 +3100,15 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3093
3100
  });
3094
3101
  defineParseLanes(objectParser, objectParseLanes);
3095
3102
  defineInheritedAnnotationParser(objectParser);
3096
- return fluent(objectParser);
3103
+ return fluent(scopeParser(objectParser, combinedOptionScope(parserPairs.map(([, p]) => p), parserPairs.map(([field]) => field)), void 0, true));
3097
3104
  }
3098
3105
  function isParserLike(value) {
3099
3106
  return value != null && (typeof value === "object" || typeof value === "function") && "parse" in value && "$valueType" in value && "$stateType" in value;
3100
3107
  }
3101
3108
  function tokenMatchesLeadingName(token, candidates) {
3102
3109
  if (token == null) return false;
3103
- for (const name of candidates.optionNames) if (token === name) return true;
3104
- for (const name of candidates.joinedOptionNames) if (name.startsWith("/") && token.startsWith(`${name}:`) || (name.startsWith("--") || name.startsWith("-") && name.length > 2) && token.startsWith(`${name}=`)) return true;
3110
+ for (const name of candidates.optionNames) if (token === name || name.startsWith("-") && !name.startsWith("--") && name.length > 2 && !/^-[^-]$/u.test(name) && token.startsWith(`${name}=`)) return true;
3111
+ for (const name of candidates.joinedOptionNames) if (/^-[^-]$/u.test(name) && token.startsWith(name) || name.startsWith("/") && token.startsWith(`${name}:`) || (name.startsWith("--") || name.startsWith("-") && name.length > 2 && !/^-[^-]$/u.test(name)) && token.startsWith(`${name}=`)) return true;
3105
3112
  for (const name of candidates.commandNames) if (token === name) return true;
3106
3113
  return false;
3107
3114
  }
@@ -3327,6 +3334,7 @@ function advanceSeqSuggestContextSync(context, parsers, initialStates) {
3327
3334
  while (currentContext.state.index < parsers.length) {
3328
3335
  const index = currentContext.state.index;
3329
3336
  const parser = parsers[index];
3337
+ currentContext = withParserOptionScope(currentContext, parser, index);
3330
3338
  const parserState = getSeqChildState(currentContext.state, index, parser);
3331
3339
  if (currentContext.buffer.length < 1) break;
3332
3340
  if (shouldAdvanceSeqBeforeParse(parser, parserState, initialStates[index], currentContext, index, parsers)) {
@@ -3353,6 +3361,7 @@ async function advanceSeqSuggestContextAsync(context, parsers, initialStates) {
3353
3361
  while (currentContext.state.index < parsers.length) {
3354
3362
  const index = currentContext.state.index;
3355
3363
  const parser = parsers[index];
3364
+ currentContext = withParserOptionScope(currentContext, parser, index);
3356
3365
  const parserState = getSeqChildState(currentContext.state, index, parser);
3357
3366
  if (currentContext.buffer.length < 1) break;
3358
3367
  if (shouldAdvanceSeqBeforeParse(parser, parserState, initialStates[index], currentContext, index, parsers)) {
@@ -4109,7 +4118,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
4109
4118
  enumerable: false
4110
4119
  });
4111
4120
  defineInheritedAnnotationParser(tupleParser);
4112
- return fluent(tupleParser);
4121
+ return fluent(scopeParser(tupleParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
4113
4122
  }
4114
4123
  function seq(...rawArgs) {
4115
4124
  const label = typeof rawArgs[0] === "string" ? rawArgs[0] : void 0;
@@ -4127,12 +4136,30 @@ function seq(...rawArgs) {
4127
4136
  ...result,
4128
4137
  consumed: consumed.length + result.consumed
4129
4138
  });
4139
+ const reachableSeqScope = (context) => {
4140
+ let end = Math.min(context.state.index + 1, parsers.length);
4141
+ while (end < parsers.length) {
4142
+ const index = end - 1;
4143
+ const child = parsers[index];
4144
+ if (context.buffer.length > 0 && !tokenMatchesLeadingName(context.buffer[0], leadingCandidatesAfter(parsers, end))) break;
4145
+ if (!parserCanSkipAt(child, getSeqChildState(context.state, index, child), context.exec, index)) break;
4146
+ end++;
4147
+ }
4148
+ return combinedOptionScope(parsers.slice(0, end), parsers.slice(0, end).map((_, index) => index));
4149
+ };
4150
+ const seqScope = selectableOptionScope(reachableSeqScope({
4151
+ state: initialState,
4152
+ buffer: [],
4153
+ usage: [],
4154
+ optionsTerminated: false
4155
+ }));
4130
4156
  const parseSync = (context) => {
4131
4157
  let currentContext = context;
4132
4158
  const allConsumed = [];
4133
4159
  while (currentContext.state.index < syncParsers.length) {
4134
4160
  const index = currentContext.state.index;
4135
4161
  const parser = syncParsers[index];
4162
+ seqScope.select(currentContext, reachableSeqScope(currentContext));
4136
4163
  const parserState = getSeqChildState(currentContext.state, index, parser);
4137
4164
  if (currentContext.buffer.length < 1) break;
4138
4165
  if (shouldAdvanceSeqBeforeParse(parser, parserState, initialState.states[index], currentContext, index, syncParsers)) {
@@ -4141,13 +4168,14 @@ function seq(...rawArgs) {
4141
4168
  currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
4142
4169
  continue;
4143
4170
  }
4144
- const result = parser.parse(withChildContext$1(currentContext, index, parserState, parser));
4171
+ const result = parser.parse(withChildContext$1(forkOptionScope(currentContext), index, parserState, parser));
4145
4172
  if (!result.success) {
4146
4173
  if (result.consumed > 0) return withSeqConsumedDepth(result, allConsumed);
4147
4174
  if (!parserCanSkipAt(parser, parserState, currentContext.exec, index)) return withSeqConsumedDepth(result, allConsumed);
4148
4175
  currentContext = advanceSeqContext(currentContext, index + 1, false);
4149
4176
  continue;
4150
4177
  }
4178
+ adoptOptionScope(currentContext, result.next);
4151
4179
  const states = updateSeqChildState(currentContext.state, index, result.next.state, parser);
4152
4180
  const nextIndex = result.consumed.length > 0 ? index : index + 1;
4153
4181
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -4175,6 +4203,7 @@ function seq(...rawArgs) {
4175
4203
  while (currentContext.state.index < parsers.length) {
4176
4204
  const index = currentContext.state.index;
4177
4205
  const parser = parsers[index];
4206
+ seqScope.select(currentContext, reachableSeqScope(currentContext));
4178
4207
  const parserState = getSeqChildState(currentContext.state, index, parser);
4179
4208
  if (currentContext.buffer.length < 1) break;
4180
4209
  if (shouldAdvanceSeqBeforeParse(parser, parserState, initialState.states[index], currentContext, index, parsers)) {
@@ -4183,13 +4212,14 @@ function seq(...rawArgs) {
4183
4212
  currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
4184
4213
  continue;
4185
4214
  }
4186
- const result = await parser.parse(withChildContext$1(currentContext, index, parserState, parser));
4215
+ const result = await parser.parse(withChildContext$1(forkOptionScope(currentContext), index, parserState, parser));
4187
4216
  if (!result.success) {
4188
4217
  if (result.consumed > 0) return withSeqConsumedDepth(result, allConsumed);
4189
4218
  if (!parserCanSkipAt(parser, parserState, currentContext.exec, index)) return withSeqConsumedDepth(result, allConsumed);
4190
4219
  currentContext = advanceSeqContext(currentContext, index + 1, false);
4191
4220
  continue;
4192
4221
  }
4222
+ adoptOptionScope(currentContext, result.next);
4193
4223
  const states = updateSeqChildState(currentContext.state, index, result.next.state, parser);
4194
4224
  const nextIndex = result.consumed.length > 0 ? index : index + 1;
4195
4225
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -4443,7 +4473,9 @@ function seq(...rawArgs) {
4443
4473
  enumerable: false
4444
4474
  });
4445
4475
  defineInheritedAnnotationParser(seqParser);
4446
- return fluent(seqParser);
4476
+ return fluent(scopeParser(seqParser, seqScope.source, (context) => {
4477
+ seqScope.select(context, reachableSeqScope(context));
4478
+ }, true));
4447
4479
  }
4448
4480
  function merge(...args) {
4449
4481
  const label = typeof args[0] === "string" ? args[0] : void 0;
@@ -5437,7 +5469,7 @@ function merge(...args) {
5437
5469
  };
5438
5470
  defineParseLanes(mergeParser, mergeParseLanes);
5439
5471
  defineInheritedAnnotationParser(mergeParser);
5440
- return fluent(mergeParser);
5472
+ return fluent(scopeParser(mergeParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
5441
5473
  }
5442
5474
  /**
5443
5475
  * Builds a dependency registry from the pre-parsed context state and returns
@@ -6064,7 +6096,7 @@ function concat(...parsers) {
6064
6096
  }
6065
6097
  };
6066
6098
  defineInheritedAnnotationParser(concatParser);
6067
- return fluent(concatParser);
6099
+ return fluent(scopeParser(concatParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
6068
6100
  }
6069
6101
  function group(label, parser, options = {}) {
6070
6102
  validateLabel(label);
@@ -6174,7 +6206,7 @@ function group(label, parser, options = {}) {
6174
6206
  configurable: true,
6175
6207
  enumerable: false
6176
6208
  });
6177
- return fluent(groupParser);
6209
+ return fluent(scopeParser(groupParser, combinedOptionScope([parser])));
6178
6210
  }
6179
6211
  /**
6180
6212
  * Creates a conditional parser that selects different branch parsers based on
@@ -6283,6 +6315,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6283
6315
  const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
6284
6316
  return options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
6285
6317
  };
6318
+ const optionScope = conditionalOptionScope(discriminator, defaultBranch, branchParsers.map(([, p]) => p));
6286
6319
  const parseSync = (context) => {
6287
6320
  const state = context.state ?? initialState;
6288
6321
  const syncDiscriminator = discriminator;
@@ -6319,10 +6352,12 @@ function conditional(discriminator, branches, defaultBranch, options) {
6319
6352
  const value = completionResult.value;
6320
6353
  const branchParser = syncBranches[value];
6321
6354
  if (branchParser) {
6355
+ const branchContext = forkOptionScope(context);
6356
+ optionScope.select(branchContext, branchParser);
6322
6357
  const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
6323
6358
  const branchParseResult = branchParser.parse({
6324
6359
  ...withChildContext$1({
6325
- ...context,
6360
+ ...branchContext,
6326
6361
  ...discriminatorExec != null ? {
6327
6362
  exec: discriminatorExec,
6328
6363
  dependencyRegistry: discriminatorExec.dependencyRegistry
@@ -6332,6 +6367,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6332
6367
  optionsTerminated: discriminatorResult.next.optionsTerminated
6333
6368
  });
6334
6369
  if (branchParseResult.success) {
6370
+ if (discriminatorResult.consumed.length > 0 || branchParseResult.consumed.length > 0) adoptOptionScope(context, branchParseResult.next);
6335
6371
  const mergedExec = mergeChildExec(discriminatorExec, branchParseResult.next.exec);
6336
6372
  const isProvisional = branchParseResult.provisional || discriminatorResult.consumed.length === 0 && branchParseResult.consumed.length === 0 && (branchParser.leadingNames.size > 0 || branchParser.acceptingAnyToken);
6337
6373
  return {
@@ -6356,26 +6392,29 @@ function conditional(discriminator, branches, defaultBranch, options) {
6356
6392
  consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
6357
6393
  };
6358
6394
  }
6359
- if (discriminatorResult.consumed.length > 0) return {
6360
- success: true,
6361
- next: {
6362
- ...discriminatorResult.next,
6363
- state: {
6364
- discriminatorState: annotatedDiscriminatorState,
6365
- discriminatorValue: value,
6366
- selectedBranch: {
6367
- kind: "branch",
6368
- key: value
6395
+ if (discriminatorResult.consumed.length > 0) {
6396
+ optionScope.select(context, branchParser);
6397
+ return {
6398
+ success: true,
6399
+ next: {
6400
+ ...discriminatorResult.next,
6401
+ state: {
6402
+ discriminatorState: annotatedDiscriminatorState,
6403
+ discriminatorValue: value,
6404
+ selectedBranch: {
6405
+ kind: "branch",
6406
+ key: value
6407
+ },
6408
+ branchState: getWrappedChildState(state, branchParser.initialState, branchParser)
6369
6409
  },
6370
- branchState: getWrappedChildState(state, branchParser.initialState, branchParser)
6410
+ ...discriminatorExec != null ? {
6411
+ exec: discriminatorExec,
6412
+ dependencyRegistry: discriminatorExec.dependencyRegistry
6413
+ } : {}
6371
6414
  },
6372
- ...discriminatorExec != null ? {
6373
- exec: discriminatorExec,
6374
- dependencyRegistry: discriminatorExec.dependencyRegistry
6375
- } : {}
6376
- },
6377
- consumed: discriminatorResult.consumed
6378
- };
6415
+ consumed: discriminatorResult.consumed
6416
+ };
6417
+ }
6379
6418
  return branchParseResult;
6380
6419
  }
6381
6420
  }
@@ -6448,7 +6487,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6448
6487
  if (discriminatorResult.consumed.length === 0 && discriminator.mode === "async") {
6449
6488
  const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
6450
6489
  const speculationContext = {
6451
- ...context,
6490
+ ...withOptionScope(context, unionLeadingNames([...branchParsers.map(([, p]) => p), ...defaultBranch ? [defaultBranch] : []])),
6452
6491
  buffer: discriminatorResult.next.buffer,
6453
6492
  optionsTerminated: discriminatorResult.next.optionsTerminated,
6454
6493
  ...discriminatorExec != null ? {
@@ -6462,7 +6501,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6462
6501
  let speculativeError;
6463
6502
  let ambiguous = false;
6464
6503
  for (const [key, bp] of branchParsers) {
6465
- const branchResult = await bp.parse(withChildContext$1(speculationContext, "_branch", bp.initialState, bp, bp.usage));
6504
+ const branchResult = await bp.parse(withChildContext$1(forkOptionScope(speculationContext), "_branch", bp.initialState, bp, bp.usage));
6466
6505
  if (branchResult.success && branchResult.consumed.length > 0) {
6467
6506
  if (branchResult.provisional) {
6468
6507
  if (provisionalHit == null && !provisionalAmbiguous) provisionalHit = {
@@ -6495,11 +6534,12 @@ function conditional(discriminator, branches, defaultBranch, options) {
6495
6534
  if (branchResult.success) {
6496
6535
  const annotatedDiscriminatorState$2 = getWrappedChildState(state, discriminatorResult.next.state, discriminator);
6497
6536
  const mergedExec = mergeChildExec(discriminatorExec, branchResult.next.exec);
6537
+ optionScope.select(context, bp);
6498
6538
  return {
6499
6539
  success: true,
6500
6540
  provisional: true,
6501
6541
  next: {
6502
- ...branchResult.next,
6542
+ ...restoreOptionScope(branchResult.next, context),
6503
6543
  state: {
6504
6544
  ...state,
6505
6545
  discriminatorState: annotatedDiscriminatorState$2,
@@ -6521,14 +6561,15 @@ function conditional(discriminator, branches, defaultBranch, options) {
6521
6561
  }
6522
6562
  let deferredBranchState = state.branchState;
6523
6563
  if (defaultBranch !== void 0 && !ambiguous && !provisionalAmbiguous) {
6524
- const defaultResult = await defaultBranch.parse(withChildContext$1(speculationContext, "_branch", state.branchState ?? defaultBranch.initialState, defaultBranch, defaultBranch.usage));
6564
+ const defaultResult = await defaultBranch.parse(withChildContext$1(forkOptionScope(speculationContext), "_branch", state.branchState ?? defaultBranch.initialState, defaultBranch, defaultBranch.usage));
6525
6565
  if (defaultResult.success && defaultResult.consumed.length > 0) {
6526
6566
  const defaultExec = mergeChildExec(discriminatorExec ?? context.exec, defaultResult.next.exec);
6567
+ optionScope.select(context, defaultBranch);
6527
6568
  return {
6528
6569
  success: true,
6529
6570
  ...defaultResult.provisional ? { provisional: true } : {},
6530
6571
  next: {
6531
- ...defaultResult.next,
6572
+ ...restoreOptionScope(defaultResult.next, context),
6532
6573
  state: {
6533
6574
  ...state,
6534
6575
  selectedBranch: { kind: "default" },
@@ -6551,7 +6592,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6551
6592
  success: true,
6552
6593
  provisional: true,
6553
6594
  next: {
6554
- ...speculationContext,
6595
+ ...restoreOptionScope(speculationContext, context),
6555
6596
  state: {
6556
6597
  ...state,
6557
6598
  discriminatorState: annotatedDiscriminatorState$1,
@@ -6567,10 +6608,12 @@ function conditional(discriminator, branches, defaultBranch, options) {
6567
6608
  const value = completionResult.value;
6568
6609
  const branchParser = branches[value];
6569
6610
  if (branchParser) {
6611
+ const branchContext = forkOptionScope(context);
6612
+ optionScope.select(branchContext, branchParser);
6570
6613
  const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
6571
6614
  const branchParseResult = await branchParser.parse({
6572
6615
  ...withChildContext$1({
6573
- ...context,
6616
+ ...branchContext,
6574
6617
  ...discriminatorExec != null ? {
6575
6618
  exec: discriminatorExec,
6576
6619
  dependencyRegistry: discriminatorExec.dependencyRegistry
@@ -6580,6 +6623,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6580
6623
  optionsTerminated: discriminatorResult.next.optionsTerminated
6581
6624
  });
6582
6625
  if (branchParseResult.success) {
6626
+ if (discriminatorResult.consumed.length > 0 || branchParseResult.consumed.length > 0) adoptOptionScope(context, branchParseResult.next);
6583
6627
  const mergedExec = mergeChildExec(discriminatorExec, branchParseResult.next.exec);
6584
6628
  return {
6585
6629
  success: true,
@@ -6603,26 +6647,29 @@ function conditional(discriminator, branches, defaultBranch, options) {
6603
6647
  consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
6604
6648
  };
6605
6649
  }
6606
- if (discriminatorResult.consumed.length > 0) return {
6607
- success: true,
6608
- next: {
6609
- ...discriminatorResult.next,
6610
- state: {
6611
- discriminatorState: annotatedDiscriminatorState,
6612
- discriminatorValue: value,
6613
- selectedBranch: {
6614
- kind: "branch",
6615
- key: value
6650
+ if (discriminatorResult.consumed.length > 0) {
6651
+ optionScope.select(context, branchParser);
6652
+ return {
6653
+ success: true,
6654
+ next: {
6655
+ ...discriminatorResult.next,
6656
+ state: {
6657
+ discriminatorState: annotatedDiscriminatorState,
6658
+ discriminatorValue: value,
6659
+ selectedBranch: {
6660
+ kind: "branch",
6661
+ key: value
6662
+ },
6663
+ branchState: getWrappedChildState(state, branchParser.initialState, branchParser)
6616
6664
  },
6617
- branchState: getWrappedChildState(state, branchParser.initialState, branchParser)
6665
+ ...discriminatorExec != null ? {
6666
+ exec: discriminatorExec,
6667
+ dependencyRegistry: discriminatorExec.dependencyRegistry
6668
+ } : {}
6618
6669
  },
6619
- ...discriminatorExec != null ? {
6620
- exec: discriminatorExec,
6621
- dependencyRegistry: discriminatorExec.dependencyRegistry
6622
- } : {}
6623
- },
6624
- consumed: discriminatorResult.consumed
6625
- };
6670
+ consumed: discriminatorResult.consumed
6671
+ };
6672
+ }
6626
6673
  return branchParseResult;
6627
6674
  }
6628
6675
  }
@@ -7296,7 +7343,9 @@ function conditional(discriminator, branches, defaultBranch, options) {
7296
7343
  } : void 0, "_discriminator"));
7297
7344
  if (discComplete.success && syncBranches[discComplete.value] !== void 0) {
7298
7345
  const resolvedBranch = syncBranches[discComplete.value];
7299
- yield* resolvedBranch.suggest(withChildContext$1(suggestContext, "_branch", state.branchState ?? resolvedBranch.initialState, resolvedBranch), prefix);
7346
+ const branchContext = forkOptionScope(suggestContext);
7347
+ optionScope.select(branchContext, resolvedBranch);
7348
+ yield* resolvedBranch.suggest(withChildContext$1(branchContext, "_branch", state.branchState ?? resolvedBranch.initialState, resolvedBranch), prefix);
7300
7349
  } else if (syncDefaultBranch !== void 0) yield* syncDefaultBranch.suggest(withChildContext$1(suggestContext, "_branch", state.branchState ?? syncDefaultBranch.initialState, syncDefaultBranch), prefix);
7301
7350
  } else {
7302
7351
  const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
@@ -7350,7 +7399,9 @@ function conditional(discriminator, branches, defaultBranch, options) {
7350
7399
  } : void 0, "_discriminator"));
7351
7400
  if (discComplete.success && branches[discComplete.value] !== void 0) {
7352
7401
  const resolvedBranch = branches[discComplete.value];
7353
- yield* resolvedBranch.suggest(withChildContext$1(suggestContext, "_branch", state.branchState ?? resolvedBranch.initialState, resolvedBranch), prefix);
7402
+ const branchContext = forkOptionScope(suggestContext);
7403
+ optionScope.select(branchContext, resolvedBranch);
7404
+ yield* resolvedBranch.suggest(withChildContext$1(branchContext, "_branch", state.branchState ?? resolvedBranch.initialState, resolvedBranch), prefix);
7354
7405
  discResolved = true;
7355
7406
  }
7356
7407
  }
@@ -7501,7 +7552,13 @@ function conditional(discriminator, branches, defaultBranch, options) {
7501
7552
  configurable: true,
7502
7553
  enumerable: false
7503
7554
  });
7504
- return fluent(conditionalParser);
7555
+ return fluent(scopeParser(conditionalParser, optionScope.source, (context) => {
7556
+ const selected = context.state?.selectedBranch;
7557
+ if (selected != null) {
7558
+ const branch = selected.kind === "default" ? defaultBranch : branches[selected.key];
7559
+ if (branch != null) optionScope.select(context, branch);
7560
+ }
7561
+ }));
7505
7562
  }
7506
7563
 
7507
7564
  //#endregion