@optique/core 1.0.0-dev.429 → 1.0.0-dev.431
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/context.d.cts +20 -2
- package/dist/context.d.ts +20 -2
- package/dist/facade.cjs +81 -51
- package/dist/facade.js +81 -51
- package/package.json +1 -1
package/dist/context.d.cts
CHANGED
|
@@ -46,6 +46,10 @@ type ParserValuePlaceholder = {
|
|
|
46
46
|
* - *Dynamic*: Data depends on parsing results (e.g., config files whose path
|
|
47
47
|
* is determined by a CLI option)
|
|
48
48
|
*
|
|
49
|
+
* Contexts may optionally implement `Disposable` or `AsyncDisposable` for
|
|
50
|
+
* cleanup. When present, `runWith()` and `runWithSync()` call the dispose
|
|
51
|
+
* method in a `finally` block after parsing completes.
|
|
52
|
+
*
|
|
49
53
|
* @template TRequiredOptions Additional options that `runWith()` must provide
|
|
50
54
|
* when this context is used. Use `void` (the default) for contexts that
|
|
51
55
|
* don't require extra options. Use {@link ParserValuePlaceholder} in option
|
|
@@ -88,7 +92,7 @@ interface SourceContext<TRequiredOptions = void> {
|
|
|
88
92
|
* Type-level marker for the required options. Not used at runtime.
|
|
89
93
|
* @internal
|
|
90
94
|
*/
|
|
91
|
-
readonly
|
|
95
|
+
readonly $requiredOptions?: TRequiredOptions;
|
|
92
96
|
/**
|
|
93
97
|
* Get annotations to inject into parsing.
|
|
94
98
|
*
|
|
@@ -103,10 +107,24 @@ interface SourceContext<TRequiredOptions = void> {
|
|
|
103
107
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
104
108
|
* Static contexts can ignore this parameter.
|
|
105
109
|
* Dynamic contexts use this to extract necessary data.
|
|
110
|
+
* @param options Optional context-required options provided by the caller
|
|
111
|
+
* of `runWith()`. These are the options declared via the
|
|
112
|
+
* `TRequiredOptions` type parameter.
|
|
106
113
|
* @returns Annotations to merge into the parsing session. Can be a Promise
|
|
107
114
|
* for async operations (e.g., loading config files).
|
|
108
115
|
*/
|
|
109
|
-
getAnnotations(parsed?: unknown): Promise<Annotations> | Annotations;
|
|
116
|
+
getAnnotations(parsed?: unknown, options?: unknown): Promise<Annotations> | Annotations;
|
|
117
|
+
/**
|
|
118
|
+
* Optional synchronous cleanup method. Called by `runWith()` and
|
|
119
|
+
* `runWithSync()` in a `finally` block after parsing completes.
|
|
120
|
+
*/
|
|
121
|
+
[Symbol.dispose]?(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Optional asynchronous cleanup method. Called by `runWith()` in a
|
|
124
|
+
* `finally` block after parsing completes. Takes precedence over
|
|
125
|
+
* `[Symbol.dispose]` in async runners.
|
|
126
|
+
*/
|
|
127
|
+
[Symbol.asyncDispose]?(): void | PromiseLike<void>;
|
|
110
128
|
}
|
|
111
129
|
/**
|
|
112
130
|
* Checks whether a context is static (returns annotations without needing
|
package/dist/context.d.ts
CHANGED
|
@@ -46,6 +46,10 @@ type ParserValuePlaceholder = {
|
|
|
46
46
|
* - *Dynamic*: Data depends on parsing results (e.g., config files whose path
|
|
47
47
|
* is determined by a CLI option)
|
|
48
48
|
*
|
|
49
|
+
* Contexts may optionally implement `Disposable` or `AsyncDisposable` for
|
|
50
|
+
* cleanup. When present, `runWith()` and `runWithSync()` call the dispose
|
|
51
|
+
* method in a `finally` block after parsing completes.
|
|
52
|
+
*
|
|
49
53
|
* @template TRequiredOptions Additional options that `runWith()` must provide
|
|
50
54
|
* when this context is used. Use `void` (the default) for contexts that
|
|
51
55
|
* don't require extra options. Use {@link ParserValuePlaceholder} in option
|
|
@@ -88,7 +92,7 @@ interface SourceContext<TRequiredOptions = void> {
|
|
|
88
92
|
* Type-level marker for the required options. Not used at runtime.
|
|
89
93
|
* @internal
|
|
90
94
|
*/
|
|
91
|
-
readonly
|
|
95
|
+
readonly $requiredOptions?: TRequiredOptions;
|
|
92
96
|
/**
|
|
93
97
|
* Get annotations to inject into parsing.
|
|
94
98
|
*
|
|
@@ -103,10 +107,24 @@ interface SourceContext<TRequiredOptions = void> {
|
|
|
103
107
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
104
108
|
* Static contexts can ignore this parameter.
|
|
105
109
|
* Dynamic contexts use this to extract necessary data.
|
|
110
|
+
* @param options Optional context-required options provided by the caller
|
|
111
|
+
* of `runWith()`. These are the options declared via the
|
|
112
|
+
* `TRequiredOptions` type parameter.
|
|
106
113
|
* @returns Annotations to merge into the parsing session. Can be a Promise
|
|
107
114
|
* for async operations (e.g., loading config files).
|
|
108
115
|
*/
|
|
109
|
-
getAnnotations(parsed?: unknown): Promise<Annotations> | Annotations;
|
|
116
|
+
getAnnotations(parsed?: unknown, options?: unknown): Promise<Annotations> | Annotations;
|
|
117
|
+
/**
|
|
118
|
+
* Optional synchronous cleanup method. Called by `runWith()` and
|
|
119
|
+
* `runWithSync()` in a `finally` block after parsing completes.
|
|
120
|
+
*/
|
|
121
|
+
[Symbol.dispose]?(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Optional asynchronous cleanup method. Called by `runWith()` in a
|
|
124
|
+
* `finally` block after parsing completes. Takes precedence over
|
|
125
|
+
* `[Symbol.dispose]` in async runners.
|
|
126
|
+
*/
|
|
127
|
+
[Symbol.asyncDispose]?(): void | PromiseLike<void>;
|
|
110
128
|
}
|
|
111
129
|
/**
|
|
112
130
|
* Checks whether a context is static (returns annotations without needing
|
package/dist/facade.cjs
CHANGED
|
@@ -820,13 +820,14 @@ function mergeAnnotations(annotationsList) {
|
|
|
820
820
|
* two-phase parsing is needed.
|
|
821
821
|
*
|
|
822
822
|
* @param contexts Source contexts to collect annotations from.
|
|
823
|
+
* @param options Optional context-required options to pass to each context.
|
|
823
824
|
* @returns Promise with merged annotations and dynamic-context hint.
|
|
824
825
|
*/
|
|
825
|
-
async function collectPhase1Annotations(contexts) {
|
|
826
|
+
async function collectPhase1Annotations(contexts, options) {
|
|
826
827
|
const annotationsList = [];
|
|
827
828
|
let hasDynamic = false;
|
|
828
829
|
for (const context of contexts) {
|
|
829
|
-
const result = context.getAnnotations();
|
|
830
|
+
const result = context.getAnnotations(void 0, options);
|
|
830
831
|
if (result instanceof Promise) {
|
|
831
832
|
hasDynamic = true;
|
|
832
833
|
annotationsList.push(await result);
|
|
@@ -845,12 +846,13 @@ async function collectPhase1Annotations(contexts) {
|
|
|
845
846
|
*
|
|
846
847
|
* @param contexts Source contexts to collect annotations from.
|
|
847
848
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
849
|
+
* @param options Optional context-required options to pass to each context.
|
|
848
850
|
* @returns Promise that resolves to merged annotations.
|
|
849
851
|
*/
|
|
850
|
-
async function collectAnnotations(contexts, parsed) {
|
|
852
|
+
async function collectAnnotations(contexts, parsed, options) {
|
|
851
853
|
const annotationsList = [];
|
|
852
854
|
for (const context of contexts) {
|
|
853
|
-
const result = context.getAnnotations(parsed);
|
|
855
|
+
const result = context.getAnnotations(parsed, options);
|
|
854
856
|
annotationsList.push(result instanceof Promise ? await result : result);
|
|
855
857
|
}
|
|
856
858
|
return mergeAnnotations(annotationsList);
|
|
@@ -860,14 +862,15 @@ async function collectAnnotations(contexts, parsed) {
|
|
|
860
862
|
* whether two-phase parsing is needed.
|
|
861
863
|
*
|
|
862
864
|
* @param contexts Source contexts to collect annotations from.
|
|
865
|
+
* @param options Optional context-required options to pass to each context.
|
|
863
866
|
* @returns Merged annotations with dynamic-context hint.
|
|
864
867
|
* @throws Error if any context returns a Promise.
|
|
865
868
|
*/
|
|
866
|
-
function collectPhase1AnnotationsSync(contexts) {
|
|
869
|
+
function collectPhase1AnnotationsSync(contexts, options) {
|
|
867
870
|
const annotationsList = [];
|
|
868
871
|
let hasDynamic = false;
|
|
869
872
|
for (const context of contexts) {
|
|
870
|
-
const result = context.getAnnotations();
|
|
873
|
+
const result = context.getAnnotations(void 0, options);
|
|
871
874
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
872
875
|
if (Object.getOwnPropertySymbols(result).length === 0) hasDynamic = true;
|
|
873
876
|
annotationsList.push(result);
|
|
@@ -882,19 +885,38 @@ function collectPhase1AnnotationsSync(contexts) {
|
|
|
882
885
|
*
|
|
883
886
|
* @param contexts Source contexts to collect annotations from.
|
|
884
887
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
888
|
+
* @param options Optional context-required options to pass to each context.
|
|
885
889
|
* @returns Merged annotations.
|
|
886
890
|
* @throws Error if any context returns a Promise.
|
|
887
891
|
*/
|
|
888
|
-
function collectAnnotationsSync(contexts, parsed) {
|
|
892
|
+
function collectAnnotationsSync(contexts, parsed, options) {
|
|
889
893
|
const annotationsList = [];
|
|
890
894
|
for (const context of contexts) {
|
|
891
|
-
const result = context.getAnnotations(parsed);
|
|
895
|
+
const result = context.getAnnotations(parsed, options);
|
|
892
896
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
893
897
|
annotationsList.push(result);
|
|
894
898
|
}
|
|
895
899
|
return mergeAnnotations(annotationsList);
|
|
896
900
|
}
|
|
897
901
|
/**
|
|
902
|
+
* Disposes all contexts that implement `AsyncDisposable` or `Disposable`.
|
|
903
|
+
* Prefers `[Symbol.asyncDispose]` over `[Symbol.dispose]`.
|
|
904
|
+
*
|
|
905
|
+
* @param contexts Source contexts to dispose.
|
|
906
|
+
*/
|
|
907
|
+
async function disposeContexts(contexts) {
|
|
908
|
+
for (const context of contexts) if (Symbol.asyncDispose in context && typeof context[Symbol.asyncDispose] === "function") await context[Symbol.asyncDispose]();
|
|
909
|
+
else if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Disposes all contexts that implement `Disposable` synchronously.
|
|
913
|
+
*
|
|
914
|
+
* @param contexts Source contexts to dispose.
|
|
915
|
+
*/
|
|
916
|
+
function disposeContextsSync(contexts) {
|
|
917
|
+
for (const context of contexts) if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
898
920
|
* Runs a parser with multiple source contexts.
|
|
899
921
|
*
|
|
900
922
|
* This function automatically handles static and dynamic contexts with proper
|
|
@@ -952,36 +974,40 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
952
974
|
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
953
975
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
954
976
|
}
|
|
955
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts);
|
|
956
|
-
if (!needsTwoPhase) {
|
|
957
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
958
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
959
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
960
|
-
}
|
|
961
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
962
|
-
let firstPassResult;
|
|
963
|
-
let firstPassFailed = false;
|
|
964
977
|
try {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
else firstPassFailed = true;
|
|
978
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
979
|
+
if (!needsTwoPhase) {
|
|
980
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
981
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
982
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
971
983
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
984
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
985
|
+
let firstPassResult;
|
|
986
|
+
let firstPassFailed = false;
|
|
987
|
+
try {
|
|
988
|
+
if (parser.$mode === "async") firstPassResult = await require_parser.parseAsync(augmentedParser1, args);
|
|
989
|
+
else firstPassResult = require_parser.parseSync(augmentedParser1, args);
|
|
990
|
+
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
991
|
+
const result = firstPassResult;
|
|
992
|
+
if (result.success) firstPassResult = result.value;
|
|
993
|
+
else firstPassFailed = true;
|
|
994
|
+
}
|
|
995
|
+
} catch {
|
|
996
|
+
firstPassFailed = true;
|
|
997
|
+
}
|
|
998
|
+
if (firstPassFailed) {
|
|
999
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1000
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1001
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1002
|
+
}
|
|
1003
|
+
const phase2Annotations = await collectAnnotations(contexts, firstPassResult, options);
|
|
1004
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1005
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1006
|
+
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1007
|
+
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1008
|
+
} finally {
|
|
1009
|
+
await disposeContexts(contexts);
|
|
979
1010
|
}
|
|
980
|
-
const phase2Annotations = await collectAnnotations(contexts, firstPassResult);
|
|
981
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
982
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
983
|
-
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
984
|
-
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
985
1011
|
}
|
|
986
1012
|
/**
|
|
987
1013
|
* Runs a synchronous parser with multiple source contexts.
|
|
@@ -1004,24 +1030,28 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1004
1030
|
const args = options?.args ?? [];
|
|
1005
1031
|
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1006
1032
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1007
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts);
|
|
1008
|
-
if (!needsTwoPhase) {
|
|
1009
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1010
|
-
return runParser(augmentedParser, programName, args, options);
|
|
1011
|
-
}
|
|
1012
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1013
|
-
let firstPassResult;
|
|
1014
1033
|
try {
|
|
1015
|
-
const
|
|
1016
|
-
if (
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1034
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1035
|
+
if (!needsTwoPhase) {
|
|
1036
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1037
|
+
return runParser(augmentedParser, programName, args, options);
|
|
1038
|
+
}
|
|
1039
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1040
|
+
let firstPassResult;
|
|
1041
|
+
try {
|
|
1042
|
+
const result = require_parser.parseSync(augmentedParser1, args);
|
|
1043
|
+
if (result.success) firstPassResult = result.value;
|
|
1044
|
+
else return runParser(augmentedParser1, programName, args, options);
|
|
1045
|
+
} catch {
|
|
1046
|
+
return runParser(augmentedParser1, programName, args, options);
|
|
1047
|
+
}
|
|
1048
|
+
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult, options);
|
|
1049
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1050
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1051
|
+
return runParser(augmentedParser2, programName, args, options);
|
|
1052
|
+
} finally {
|
|
1053
|
+
disposeContextsSync(contexts);
|
|
1020
1054
|
}
|
|
1021
|
-
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult);
|
|
1022
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1023
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1024
|
-
return runParser(augmentedParser2, programName, args, options);
|
|
1025
1055
|
}
|
|
1026
1056
|
/**
|
|
1027
1057
|
* Runs any parser asynchronously with multiple source contexts.
|
package/dist/facade.js
CHANGED
|
@@ -820,13 +820,14 @@ function mergeAnnotations(annotationsList) {
|
|
|
820
820
|
* two-phase parsing is needed.
|
|
821
821
|
*
|
|
822
822
|
* @param contexts Source contexts to collect annotations from.
|
|
823
|
+
* @param options Optional context-required options to pass to each context.
|
|
823
824
|
* @returns Promise with merged annotations and dynamic-context hint.
|
|
824
825
|
*/
|
|
825
|
-
async function collectPhase1Annotations(contexts) {
|
|
826
|
+
async function collectPhase1Annotations(contexts, options) {
|
|
826
827
|
const annotationsList = [];
|
|
827
828
|
let hasDynamic = false;
|
|
828
829
|
for (const context of contexts) {
|
|
829
|
-
const result = context.getAnnotations();
|
|
830
|
+
const result = context.getAnnotations(void 0, options);
|
|
830
831
|
if (result instanceof Promise) {
|
|
831
832
|
hasDynamic = true;
|
|
832
833
|
annotationsList.push(await result);
|
|
@@ -845,12 +846,13 @@ async function collectPhase1Annotations(contexts) {
|
|
|
845
846
|
*
|
|
846
847
|
* @param contexts Source contexts to collect annotations from.
|
|
847
848
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
849
|
+
* @param options Optional context-required options to pass to each context.
|
|
848
850
|
* @returns Promise that resolves to merged annotations.
|
|
849
851
|
*/
|
|
850
|
-
async function collectAnnotations(contexts, parsed) {
|
|
852
|
+
async function collectAnnotations(contexts, parsed, options) {
|
|
851
853
|
const annotationsList = [];
|
|
852
854
|
for (const context of contexts) {
|
|
853
|
-
const result = context.getAnnotations(parsed);
|
|
855
|
+
const result = context.getAnnotations(parsed, options);
|
|
854
856
|
annotationsList.push(result instanceof Promise ? await result : result);
|
|
855
857
|
}
|
|
856
858
|
return mergeAnnotations(annotationsList);
|
|
@@ -860,14 +862,15 @@ async function collectAnnotations(contexts, parsed) {
|
|
|
860
862
|
* whether two-phase parsing is needed.
|
|
861
863
|
*
|
|
862
864
|
* @param contexts Source contexts to collect annotations from.
|
|
865
|
+
* @param options Optional context-required options to pass to each context.
|
|
863
866
|
* @returns Merged annotations with dynamic-context hint.
|
|
864
867
|
* @throws Error if any context returns a Promise.
|
|
865
868
|
*/
|
|
866
|
-
function collectPhase1AnnotationsSync(contexts) {
|
|
869
|
+
function collectPhase1AnnotationsSync(contexts, options) {
|
|
867
870
|
const annotationsList = [];
|
|
868
871
|
let hasDynamic = false;
|
|
869
872
|
for (const context of contexts) {
|
|
870
|
-
const result = context.getAnnotations();
|
|
873
|
+
const result = context.getAnnotations(void 0, options);
|
|
871
874
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
872
875
|
if (Object.getOwnPropertySymbols(result).length === 0) hasDynamic = true;
|
|
873
876
|
annotationsList.push(result);
|
|
@@ -882,19 +885,38 @@ function collectPhase1AnnotationsSync(contexts) {
|
|
|
882
885
|
*
|
|
883
886
|
* @param contexts Source contexts to collect annotations from.
|
|
884
887
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
888
|
+
* @param options Optional context-required options to pass to each context.
|
|
885
889
|
* @returns Merged annotations.
|
|
886
890
|
* @throws Error if any context returns a Promise.
|
|
887
891
|
*/
|
|
888
|
-
function collectAnnotationsSync(contexts, parsed) {
|
|
892
|
+
function collectAnnotationsSync(contexts, parsed, options) {
|
|
889
893
|
const annotationsList = [];
|
|
890
894
|
for (const context of contexts) {
|
|
891
|
-
const result = context.getAnnotations(parsed);
|
|
895
|
+
const result = context.getAnnotations(parsed, options);
|
|
892
896
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
893
897
|
annotationsList.push(result);
|
|
894
898
|
}
|
|
895
899
|
return mergeAnnotations(annotationsList);
|
|
896
900
|
}
|
|
897
901
|
/**
|
|
902
|
+
* Disposes all contexts that implement `AsyncDisposable` or `Disposable`.
|
|
903
|
+
* Prefers `[Symbol.asyncDispose]` over `[Symbol.dispose]`.
|
|
904
|
+
*
|
|
905
|
+
* @param contexts Source contexts to dispose.
|
|
906
|
+
*/
|
|
907
|
+
async function disposeContexts(contexts) {
|
|
908
|
+
for (const context of contexts) if (Symbol.asyncDispose in context && typeof context[Symbol.asyncDispose] === "function") await context[Symbol.asyncDispose]();
|
|
909
|
+
else if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Disposes all contexts that implement `Disposable` synchronously.
|
|
913
|
+
*
|
|
914
|
+
* @param contexts Source contexts to dispose.
|
|
915
|
+
*/
|
|
916
|
+
function disposeContextsSync(contexts) {
|
|
917
|
+
for (const context of contexts) if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
898
920
|
* Runs a parser with multiple source contexts.
|
|
899
921
|
*
|
|
900
922
|
* This function automatically handles static and dynamic contexts with proper
|
|
@@ -952,36 +974,40 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
952
974
|
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
953
975
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
954
976
|
}
|
|
955
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts);
|
|
956
|
-
if (!needsTwoPhase) {
|
|
957
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
958
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
959
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
960
|
-
}
|
|
961
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
962
|
-
let firstPassResult;
|
|
963
|
-
let firstPassFailed = false;
|
|
964
977
|
try {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
else firstPassFailed = true;
|
|
978
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
979
|
+
if (!needsTwoPhase) {
|
|
980
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
981
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
982
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
971
983
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
984
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
985
|
+
let firstPassResult;
|
|
986
|
+
let firstPassFailed = false;
|
|
987
|
+
try {
|
|
988
|
+
if (parser.$mode === "async") firstPassResult = await parseAsync(augmentedParser1, args);
|
|
989
|
+
else firstPassResult = parseSync(augmentedParser1, args);
|
|
990
|
+
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
991
|
+
const result = firstPassResult;
|
|
992
|
+
if (result.success) firstPassResult = result.value;
|
|
993
|
+
else firstPassFailed = true;
|
|
994
|
+
}
|
|
995
|
+
} catch {
|
|
996
|
+
firstPassFailed = true;
|
|
997
|
+
}
|
|
998
|
+
if (firstPassFailed) {
|
|
999
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1000
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1001
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1002
|
+
}
|
|
1003
|
+
const phase2Annotations = await collectAnnotations(contexts, firstPassResult, options);
|
|
1004
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1005
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1006
|
+
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1007
|
+
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1008
|
+
} finally {
|
|
1009
|
+
await disposeContexts(contexts);
|
|
979
1010
|
}
|
|
980
|
-
const phase2Annotations = await collectAnnotations(contexts, firstPassResult);
|
|
981
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
982
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
983
|
-
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
984
|
-
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
985
1011
|
}
|
|
986
1012
|
/**
|
|
987
1013
|
* Runs a synchronous parser with multiple source contexts.
|
|
@@ -1004,24 +1030,28 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1004
1030
|
const args = options?.args ?? [];
|
|
1005
1031
|
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1006
1032
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1007
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts);
|
|
1008
|
-
if (!needsTwoPhase) {
|
|
1009
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1010
|
-
return runParser(augmentedParser, programName, args, options);
|
|
1011
|
-
}
|
|
1012
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1013
|
-
let firstPassResult;
|
|
1014
1033
|
try {
|
|
1015
|
-
const
|
|
1016
|
-
if (
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1034
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1035
|
+
if (!needsTwoPhase) {
|
|
1036
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1037
|
+
return runParser(augmentedParser, programName, args, options);
|
|
1038
|
+
}
|
|
1039
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1040
|
+
let firstPassResult;
|
|
1041
|
+
try {
|
|
1042
|
+
const result = parseSync(augmentedParser1, args);
|
|
1043
|
+
if (result.success) firstPassResult = result.value;
|
|
1044
|
+
else return runParser(augmentedParser1, programName, args, options);
|
|
1045
|
+
} catch {
|
|
1046
|
+
return runParser(augmentedParser1, programName, args, options);
|
|
1047
|
+
}
|
|
1048
|
+
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult, options);
|
|
1049
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1050
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1051
|
+
return runParser(augmentedParser2, programName, args, options);
|
|
1052
|
+
} finally {
|
|
1053
|
+
disposeContextsSync(contexts);
|
|
1020
1054
|
}
|
|
1021
|
-
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult);
|
|
1022
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1023
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1024
|
-
return runParser(augmentedParser2, programName, args, options);
|
|
1025
1055
|
}
|
|
1026
1056
|
/**
|
|
1027
1057
|
* Runs any parser asynchronously with multiple source contexts.
|