@futpib/parser 1.0.2 → 1.0.4
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/.github/copilot-instructions.md +149 -0
- package/.github/workflows/copilot-setup-steps.yml +18 -0
- package/.github/workflows/main.yml +29 -8
- package/.yarn/releases/yarn-4.9.4.cjs +942 -0
- package/.yarnrc.yml +1 -1
- package/build/allSettledStream.js +1 -1
- package/build/allSettledStream.test.js +2 -2
- package/build/androidPackageParser.d.ts +1 -1
- package/build/androidPackageParser.js +5 -3
- package/build/androidPackageParser.test.js +7 -7
- package/build/androidPackageUnparser.d.ts +2 -2
- package/build/androidPackageUnparser.js +18 -14
- package/build/androidPackageUnparser.test.js +7 -7
- package/build/arbitrarilySlicedAsyncInterator.js +2 -1
- package/build/arbitraryDalvikBytecode.d.ts +4 -0
- package/build/arbitraryDalvikBytecode.js +640 -0
- package/build/arbitraryDalvikExecutable.d.ts +3 -0
- package/build/arbitraryDalvikExecutable.js +282 -0
- package/build/arbitraryDosDateTime.js +1 -0
- package/build/arbitraryZipStream.js +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayUnparser.d.ts +1 -1
- package/build/backsmali.d.ts +3 -1
- package/build/backsmali.js +31 -3
- package/build/bash.d.ts +84 -0
- package/build/bash.js +1 -0
- package/build/bashParser.d.ts +6 -0
- package/build/bashParser.js +294 -0
- package/build/bashParser.test.d.ts +1 -0
- package/build/bashParser.test.js +181 -0
- package/build/customInvariant.d.ts +2 -1
- package/build/customInvariant.js +4 -6
- package/build/dalvikBytecodeParser/formatParsers.d.ts +76 -2
- package/build/dalvikBytecodeParser/formatParsers.js +146 -11
- package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
- package/build/dalvikBytecodeParser/formatSizes.js +34 -0
- package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
- package/build/dalvikBytecodeParser/operationFormats.js +225 -0
- package/build/dalvikBytecodeParser.d.ts +1105 -5
- package/build/dalvikBytecodeParser.js +658 -205
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
- package/build/dalvikBytecodeUnparser.d.ts +3 -0
- package/build/dalvikBytecodeUnparser.js +642 -0
- package/build/dalvikBytecodeUnparser.test.d.ts +1 -0
- package/build/dalvikBytecodeUnparser.test.js +25 -0
- package/build/dalvikExecutable.d.ts +65 -8
- package/build/dalvikExecutable.js +36 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +1 -1
- package/build/dalvikExecutableParser/stringSyntaxParser.js +17 -17
- package/build/dalvikExecutableParser/typeParsers.d.ts +2 -1
- package/build/dalvikExecutableParser/typeParsers.js +16 -11
- package/build/dalvikExecutableParser/typedNumbers.d.ts +85 -69
- package/build/dalvikExecutableParser/typedNumbers.js +0 -1
- package/build/dalvikExecutableParser.d.ts +2 -2
- package/build/dalvikExecutableParser.js +655 -337
- package/build/dalvikExecutableParser.test.js +24 -22
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +223 -246
- package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
- package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
- package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
- package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
- package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
- package/build/dalvikExecutableUnparser/utils.js +108 -0
- package/build/dalvikExecutableUnparser.d.ts +4 -0
- package/build/dalvikExecutableUnparser.js +406 -0
- package/build/dalvikExecutableUnparser.test.d.ts +1 -0
- package/build/dalvikExecutableUnparser.test.js +31 -0
- package/build/debugLogInputParser.js +1 -1
- package/build/disjunctionParser.d.ts +2 -2
- package/build/disjunctionParser.js +2 -2
- package/build/elementTerminatedArrayParser.d.ts +2 -2
- package/build/elementTerminatedArrayParser.js +1 -1
- package/build/elementTerminatedArrayParser.test.js +5 -5
- package/build/elementTerminatedSequenceArrayParser.d.ts +2 -2
- package/build/elementTerminatedSequenceArrayParser.js +1 -1
- package/build/elementTerminatedSequenceArrayParser.test.js +2 -2
- package/build/elementTerminatedSequenceParser.d.ts +2 -2
- package/build/elementTerminatedSequenceParser.js +1 -1
- package/build/elementTerminatedSequenceParser.test.js +2 -2
- package/build/endOfInputParser.d.ts +1 -1
- package/build/exactElementSwitchParser.d.ts +3 -0
- package/build/exactElementSwitchParser.js +22 -0
- package/build/fetchCid.js +2 -6
- package/build/fetchCid.test.d.ts +1 -0
- package/build/fetchCid.test.js +16 -0
- package/build/fixedLengthSequenceParser.test.js +2 -2
- package/build/hasExecutable.js +2 -2
- package/build/highResolutionTimer.js +1 -1
- package/build/index.d.ts +24 -2
- package/build/index.js +22 -1
- package/build/inputReader.d.ts +1 -1
- package/build/inputReader.test.js +33 -45
- package/build/javaKeyStoreParser.test.js +6 -6
- package/build/jsonParser.js +8 -8
- package/build/lazyMessageError.d.ts +48 -0
- package/build/lazyMessageError.js +53 -0
- package/build/lazyMessageError.test.d.ts +1 -0
- package/build/lazyMessageError.test.js +15 -0
- package/build/leb128Parser.d.ts +1 -1
- package/build/leb128Parser.js +10 -10
- package/build/leb128Parser.test.js +7 -7
- package/build/negativeLookaheadParser.js +2 -2
- package/build/negativeLookaheadParser.test.js +4 -4
- package/build/noStackCaptureOverheadError.d.ts +4 -0
- package/build/noStackCaptureOverheadError.js +9 -0
- package/build/noStackCaptureOverheadError.test.d.ts +1 -0
- package/build/noStackCaptureOverheadError.test.js +15 -0
- package/build/nonEmptyArrayParser.js +2 -2
- package/build/nonEmptyArrayParser.test.js +2 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +2 -1
- package/build/parser.js +23 -8
- package/build/parser.test.js +78 -29
- package/build/parserConsumedSequenceParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.js +2 -2
- package/build/parserContext.d.ts +8 -6
- package/build/parserContext.js +60 -33
- package/build/parserContext.test.js +7 -3
- package/build/parserError.d.ts +603 -44
- package/build/parserError.js +98 -53
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.js +2 -2
- package/build/promiseCompose.js +1 -2
- package/build/regexpParser.d.ts +2 -0
- package/build/regexpParser.js +71 -0
- package/build/regexpParser.test.d.ts +1 -0
- package/build/regexpParser.test.js +83 -0
- package/build/regularExpression.d.ts +63 -0
- package/build/regularExpression.js +1 -0
- package/build/regularExpressionParser.d.ts +3 -0
- package/build/regularExpressionParser.js +580 -0
- package/build/regularExpressionParser.test.d.ts +1 -0
- package/build/regularExpressionParser.test.js +89 -0
- package/build/separatedArrayParser.js +2 -2
- package/build/separatedNonEmptyArrayParser.d.ts +2 -0
- package/build/separatedNonEmptyArrayParser.js +40 -0
- package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
- package/build/separatedNonEmptyArrayParser.test.js +66 -0
- package/build/sequenceBuffer.js +1 -1
- package/build/sequenceTerminatedSequenceParser.d.ts +2 -2
- package/build/sequenceTerminatedSequenceParser.js +3 -3
- package/build/sequenceTerminatedSequenceParser.test.js +1 -1
- package/build/sequenceUnparser.d.ts +1 -1
- package/build/skipToParser.d.ts +1 -1
- package/build/skipToParser.js +2 -2
- package/build/sliceBoundedParser.test.js +4 -9
- package/build/smali.d.ts +1 -1
- package/build/smali.js +6 -2
- package/build/smaliParser.d.ts +62 -6
- package/build/smaliParser.js +1721 -296
- package/build/smaliParser.test.js +338 -43
- package/build/stringFromAsyncIterable.d.ts +1 -0
- package/build/stringFromAsyncIterable.js +7 -0
- package/build/terminatedArrayParser.js +4 -4
- package/build/terminatedArrayParser.test.js +7 -7
- package/build/toAsyncIterator.js +4 -4
- package/build/unionParser.d.ts +1 -1
- package/build/unionParser.js +2 -2
- package/build/unionParser.test.js +3 -3
- package/build/unparser.d.ts +3 -3
- package/build/unparser.js +6 -4
- package/build/unparser.test.js +7 -19
- package/build/unparserContext.d.ts +2 -2
- package/build/unparserContext.js +2 -3
- package/build/unparserError.d.ts +2 -1
- package/build/unparserError.js +2 -1
- package/build/unparserImplementationInvariant.d.ts +1 -1
- package/build/unparserOutputCompanion.d.ts +1 -1
- package/build/unparserOutputCompanion.js +1 -1
- package/build/zipParser.js +1 -1
- package/build/zipUnparser.d.ts +3 -3
- package/build/zipUnparser.js +9 -19
- package/build/zipUnparser.test.js +1 -1
- package/package.json +20 -26
- package/src/allSettledStream.test.ts +2 -2
- package/src/allSettledStream.ts +3 -3
- package/src/androidPackageParser.test.ts +17 -19
- package/src/androidPackageParser.ts +129 -171
- package/src/androidPackageUnparser.test.ts +19 -21
- package/src/androidPackageUnparser.ts +23 -17
- package/src/arbitrarilySlicedAsyncInterable.ts +1 -1
- package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
- package/src/arbitraryDalvikBytecode.ts +992 -0
- package/src/arbitraryDalvikExecutable.ts +434 -0
- package/src/arbitraryDosDateTime.ts +1 -0
- package/src/arbitraryZipStream.ts +1 -1
- package/src/arrayParser.ts +2 -2
- package/src/arrayUnparser.ts +2 -2
- package/src/backsmali.ts +48 -4
- package/src/bash.ts +120 -0
- package/src/bashParser.test.ts +332 -0
- package/src/bashParser.ts +461 -0
- package/src/bsonParser.test.ts +12 -14
- package/src/customInvariant.ts +8 -12
- package/src/dalvikBytecodeParser/formatParsers.ts +376 -17
- package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
- package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
- package/src/dalvikBytecodeParser.ts +1042 -243
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
- package/src/dalvikBytecodeUnparser.test.ts +44 -0
- package/src/dalvikBytecodeUnparser.ts +758 -0
- package/src/dalvikExecutable.ts +110 -48
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +33 -33
- package/src/dalvikExecutableParser/typeParsers.ts +23 -14
- package/src/dalvikExecutableParser/typedNumbers.ts +19 -19
- package/src/dalvikExecutableParser.test.ts +60 -60
- package/src/dalvikExecutableParser.test.ts.md +6 -6
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +911 -434
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +256 -239
- package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
- package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
- package/src/dalvikExecutableUnparser/utils.ts +149 -0
- package/src/dalvikExecutableUnparser.test.ts +57 -0
- package/src/dalvikExecutableUnparser.ts +581 -0
- package/src/debugLogInputParser.ts +1 -1
- package/src/disjunctionParser.ts +5 -5
- package/src/elementTerminatedArrayParser.test.ts +8 -8
- package/src/elementTerminatedArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceArrayParser.test.ts +4 -6
- package/src/elementTerminatedSequenceArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceParser.test.ts +4 -6
- package/src/elementTerminatedSequenceParser.ts +2 -2
- package/src/endOfInputParser.ts +1 -1
- package/src/exactElementSwitchParser.ts +41 -0
- package/src/fetchCid.test.ts +20 -0
- package/src/fetchCid.ts +3 -7
- package/src/fixedLengthSequenceParser.test.ts +10 -12
- package/src/hasExecutable.ts +2 -2
- package/src/highResolutionTimer.ts +1 -1
- package/src/index.ts +113 -2
- package/src/inputReader.test.ts +39 -52
- package/src/inputReader.ts +2 -4
- package/src/inputReaderState.ts +1 -1
- package/src/inspect.ts +1 -1
- package/src/javaKeyStoreParser.test.ts +12 -14
- package/src/javaKeyStoreParser.ts +2 -6
- package/src/jsonParser.test.ts +2 -4
- package/src/jsonParser.ts +34 -38
- package/src/lazyMessageError.test.ts +21 -0
- package/src/lazyMessageError.ts +88 -0
- package/src/leb128Parser.test.ts +25 -23
- package/src/leb128Parser.ts +19 -19
- package/src/negativeLookaheadParser.test.ts +7 -11
- package/src/negativeLookaheadParser.ts +2 -2
- package/src/noStackCaptureOverheadError.test.ts +17 -0
- package/src/noStackCaptureOverheadError.ts +12 -0
- package/src/nonEmptyArrayParser.test.ts +3 -2
- package/src/nonEmptyArrayParser.ts +2 -2
- package/src/optionalParser.ts +2 -2
- package/src/parser.test.ts +96 -43
- package/src/parser.test.ts.md +13 -6
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +35 -12
- package/src/parserAccessorParser.ts +1 -1
- package/src/parserConsumedSequenceParser.ts +3 -3
- package/src/parserContext.test.ts +7 -3
- package/src/parserContext.ts +82 -48
- package/src/parserError.ts +143 -63
- package/src/parserImplementationInvariant.ts +3 -3
- package/src/parserInputCompanion.ts +2 -2
- package/src/promiseCompose.ts +2 -2
- package/src/regexpParser.test.ts +186 -0
- package/src/regexpParser.ts +94 -0
- package/src/regularExpression.ts +24 -0
- package/src/regularExpressionParser.test.ts +102 -0
- package/src/regularExpressionParser.ts +921 -0
- package/src/separatedArrayParser.ts +3 -3
- package/src/separatedNonEmptyArrayParser.test.ts +117 -0
- package/src/separatedNonEmptyArrayParser.ts +61 -0
- package/src/sequenceBuffer.test.ts +9 -9
- package/src/sequenceBuffer.ts +4 -4
- package/src/sequenceTerminatedSequenceParser.test.ts +3 -5
- package/src/sequenceTerminatedSequenceParser.ts +4 -4
- package/src/sequenceUnparser.ts +2 -2
- package/src/skipToParser.ts +2 -2
- package/src/sliceBoundedParser.test.ts +4 -12
- package/src/sliceBoundedParser.ts +2 -2
- package/src/smali.ts +8 -3
- package/src/smaliParser.test.ts +377 -66
- package/src/smaliParser.test.ts.md +1635 -48
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +2751 -569
- package/src/stringFromAsyncIterable.ts +9 -0
- package/src/terminatedArrayParser.test.ts +11 -11
- package/src/terminatedArrayParser.ts +5 -7
- package/src/toAsyncIterator.ts +8 -8
- package/src/uint8Array.ts +2 -3
- package/src/unionParser.test.ts +22 -23
- package/src/unionParser.ts +6 -8
- package/src/unparser.test.ts +18 -34
- package/src/unparser.ts +13 -9
- package/src/unparserContext.ts +9 -13
- package/src/unparserError.ts +2 -1
- package/src/unparserImplementationInvariant.ts +1 -1
- package/src/unparserOutputCompanion.ts +1 -1
- package/src/zip.ts +2 -6
- package/src/zipParser.ts +10 -18
- package/src/zipUnparser.test.ts +1 -1
- package/src/zipUnparser.ts +52 -64
- package/tsconfig.json +7 -1
- package/xo.config.ts +15 -0
- package/.yarn/releases/yarn-4.5.3.cjs +0 -934
package/src/parser.test.ts
CHANGED
|
@@ -4,14 +4,10 @@ import { createUnionParser } from './unionParser.js';
|
|
|
4
4
|
import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
|
|
5
5
|
import { stringParserInputCompanion, uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
6
6
|
import {
|
|
7
|
+
isParserParsingJoinError,
|
|
8
|
+
normalParserErrorModule,
|
|
7
9
|
ParserError,
|
|
8
|
-
ParserParsingInvariantError,
|
|
9
|
-
ParserParsingJoinAllError,
|
|
10
|
-
ParserParsingJoinDeepestError,
|
|
11
10
|
ParserParsingJoinError,
|
|
12
|
-
ParserParsingJoinFurthestError,
|
|
13
|
-
ParserParsingJoinNoneError,
|
|
14
|
-
ParserUnexpectedRemainingInputError,
|
|
15
11
|
} from './parserError.js';
|
|
16
12
|
import { createTupleParser } from './tupleParser.js';
|
|
17
13
|
import { promiseCompose } from './promiseCompose.js';
|
|
@@ -20,6 +16,7 @@ import { createExactSequenceNaiveParser } from './exactSequenceParser.js';
|
|
|
20
16
|
import { createArrayParser } from './arrayParser.js';
|
|
21
17
|
import { createElementParser } from './elementParser.js';
|
|
22
18
|
import { toAsyncIterable } from './toAsyncIterable.js';
|
|
19
|
+
import { stringFromAsyncIterable } from './stringFromAsyncIterable.js';
|
|
23
20
|
|
|
24
21
|
const aUnionParser = createUnionParser<string, string>([
|
|
25
22
|
createExactSequenceNaiveParser('1'),
|
|
@@ -54,74 +51,66 @@ async function * asyncIteratorFromString(string: string) {
|
|
|
54
51
|
yield string;
|
|
55
52
|
}
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
let string = '';
|
|
59
|
-
|
|
60
|
-
for await (const chunk of asyncIterable) {
|
|
61
|
-
string += chunk;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return string;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function sortChildErrors(error: ParserParsingJoinNoneError) {
|
|
54
|
+
function sortChildErrors(error: ParserParsingJoinError) {
|
|
68
55
|
error.childErrors.sort((a, b) => a.message.localeCompare(b.message));
|
|
69
56
|
|
|
70
57
|
for (const childError of error.childErrors) {
|
|
71
|
-
if (childError
|
|
58
|
+
if (isParserParsingJoinError(childError)) {
|
|
72
59
|
sortChildErrors(childError);
|
|
73
60
|
}
|
|
74
61
|
}
|
|
75
62
|
}
|
|
76
63
|
|
|
77
|
-
function removeStackLocations(errorStack: string) {
|
|
78
|
-
return errorStack
|
|
64
|
+
function removeStackLocations(errorStack: string | undefined) {
|
|
65
|
+
return errorStack?.replaceAll(/((at [^\n]+)[\s\n]+)+(at [^\n]+)/g, 'at [LOCATIONS]');
|
|
79
66
|
}
|
|
80
67
|
|
|
81
68
|
test('errorJoinMode: none', async t => {
|
|
82
69
|
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
83
70
|
errorJoinMode: 'none',
|
|
71
|
+
errorStack: true,
|
|
84
72
|
}), {
|
|
85
|
-
instanceOf: ParserParsingJoinNoneError,
|
|
73
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinNoneError,
|
|
86
74
|
});
|
|
87
75
|
|
|
88
76
|
t.is(error.position, 12);
|
|
89
77
|
t.deepEqual(error.childErrors, []);
|
|
90
78
|
|
|
91
|
-
t.snapshot(removeStackLocations(error.stack
|
|
79
|
+
t.snapshot(removeStackLocations(error.stack));
|
|
92
80
|
});
|
|
93
81
|
|
|
94
82
|
test('errorJoinMode: all', async t => {
|
|
95
83
|
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
96
84
|
errorJoinMode: 'all',
|
|
85
|
+
errorStack: true,
|
|
97
86
|
}), {
|
|
98
|
-
instanceOf: ParserParsingJoinAllError,
|
|
87
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinAllError,
|
|
99
88
|
});
|
|
100
89
|
|
|
101
90
|
sortChildErrors(error);
|
|
102
91
|
|
|
103
|
-
t.snapshot(removeStackLocations(error.stack
|
|
92
|
+
t.snapshot(removeStackLocations(error.stack));
|
|
104
93
|
|
|
105
94
|
t.is(error.position, 12, 'error.position');
|
|
106
95
|
t.is(error.childErrors.length, 4);
|
|
107
96
|
|
|
108
97
|
const error1 = error.childErrors.at(-1)!;
|
|
109
98
|
|
|
110
|
-
invariant(error1
|
|
99
|
+
invariant(isParserParsingJoinError(error1), 'error1 instanceof ParserParsingJoinAllError');
|
|
111
100
|
|
|
112
101
|
t.is(error1.position, 3, 'error1.position');
|
|
113
102
|
t.is(error1.childErrors.length, 4);
|
|
114
103
|
|
|
115
104
|
const error2 = error1.childErrors.at(-1)!;
|
|
116
105
|
|
|
117
|
-
invariant(error2
|
|
106
|
+
invariant(isParserParsingJoinError(error2), 'error2 instanceof ParserParsingJoinAllError');
|
|
118
107
|
|
|
119
108
|
t.is(error2.position, 4, 'error2.position');
|
|
120
109
|
t.is(error2.childErrors.length, 3);
|
|
121
110
|
|
|
122
111
|
const error3 = error2.childErrors.at(-1)!;
|
|
123
112
|
|
|
124
|
-
invariant(error3
|
|
113
|
+
invariant(error3.name === 'ParserParsingInvariantError', 'error3 instanceof ParserParsingInvariantError');
|
|
125
114
|
|
|
126
115
|
t.is(error3.position, 4, 'error3.position');
|
|
127
116
|
});
|
|
@@ -129,34 +118,35 @@ test('errorJoinMode: all', async t => {
|
|
|
129
118
|
test('errorJoinMode: deepest', async t => {
|
|
130
119
|
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
131
120
|
errorJoinMode: 'deepest',
|
|
121
|
+
errorStack: true,
|
|
132
122
|
}), {
|
|
133
|
-
instanceOf: ParserParsingJoinDeepestError,
|
|
123
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinDeepestError,
|
|
134
124
|
});
|
|
135
125
|
|
|
136
126
|
sortChildErrors(error);
|
|
137
127
|
|
|
138
|
-
t.snapshot(removeStackLocations(error.stack
|
|
128
|
+
t.snapshot(removeStackLocations(error.stack));
|
|
139
129
|
|
|
140
130
|
t.is(error.position, 12);
|
|
141
131
|
t.is(error.childErrors.length, 1);
|
|
142
132
|
|
|
143
133
|
const error1 = error.childErrors.at(-1)!;
|
|
144
134
|
|
|
145
|
-
invariant(error1
|
|
135
|
+
invariant(isParserParsingJoinError(error1), 'error1 instanceof ParserParsingJoinDeepestError');
|
|
146
136
|
|
|
147
137
|
t.is(error1.position, 3);
|
|
148
138
|
t.is(error1.childErrors.length, 1);
|
|
149
139
|
|
|
150
140
|
const error2 = error1.childErrors.at(-1)!;
|
|
151
141
|
|
|
152
|
-
invariant(error2
|
|
142
|
+
invariant(isParserParsingJoinError(error2), 'error2 instanceof ParserParsingJoinDeepestError');
|
|
153
143
|
|
|
154
144
|
t.is(error2.position, 4);
|
|
155
145
|
t.is(error2.childErrors.length, 3);
|
|
156
146
|
|
|
157
147
|
const error3 = error2.childErrors.at(-1)!;
|
|
158
148
|
|
|
159
|
-
invariant(error3
|
|
149
|
+
invariant(error3.name === 'ParserParsingInvariantError', 'error3 instanceof ParserParsingInvariantError');
|
|
160
150
|
|
|
161
151
|
t.is(error3.position, 4);
|
|
162
152
|
});
|
|
@@ -164,24 +154,83 @@ test('errorJoinMode: deepest', async t => {
|
|
|
164
154
|
test('errorJoinMode: furthest', async t => {
|
|
165
155
|
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
166
156
|
errorJoinMode: 'furthest',
|
|
157
|
+
errorStack: true,
|
|
167
158
|
}), {
|
|
168
|
-
instanceOf: ParserParsingJoinFurthestError,
|
|
159
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinFurthestError,
|
|
169
160
|
});
|
|
170
161
|
|
|
171
162
|
sortChildErrors(error);
|
|
172
163
|
|
|
173
|
-
t.snapshot(removeStackLocations(error.stack
|
|
164
|
+
t.snapshot(removeStackLocations(error.stack));
|
|
174
165
|
|
|
175
166
|
t.is(error.position, 12);
|
|
176
167
|
t.is(error.childErrors.length, 1);
|
|
177
168
|
|
|
178
169
|
const error1 = error.childErrors.at(-1)!;
|
|
179
170
|
|
|
180
|
-
invariant(error1
|
|
171
|
+
invariant(error1.name === 'ParserParsingInvariantError', 'error1 instanceof ParserParsingInvariantError');
|
|
181
172
|
|
|
182
173
|
t.is(error1.position, 12);
|
|
183
174
|
});
|
|
184
175
|
|
|
176
|
+
test('errorStack: false', async t => {
|
|
177
|
+
const error = await t.throwsAsync(runParser(sampleParser, 'nothing like what sampleParser expects', stringParserInputCompanion, {
|
|
178
|
+
errorJoinMode: 'all',
|
|
179
|
+
}), {
|
|
180
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinAllError,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
t.regex(error.stack!, /intentionally left blank/);
|
|
184
|
+
t.regex(error.stack!, /errorStack: true/);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('errorStack: true', async t => {
|
|
188
|
+
const error = await t.throwsAsync(runParser(sampleParser, 'nothing like what sampleParser expects', stringParserInputCompanion, {
|
|
189
|
+
errorJoinMode: 'all',
|
|
190
|
+
errorStack: true,
|
|
191
|
+
}), {
|
|
192
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinAllError,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
t.regex(error.stack!, /exactSequenceParser/);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('errorJoinMode: none, errorStack: false', async t => {
|
|
199
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
200
|
+
errorJoinMode: 'none',
|
|
201
|
+
errorStack: false,
|
|
202
|
+
}), {
|
|
203
|
+
instanceOf: normalParserErrorModule.ParserParsingJoinNoneError,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
t.is(error.position, 12);
|
|
207
|
+
t.deepEqual(error.childErrors, []);
|
|
208
|
+
|
|
209
|
+
t.snapshot(removeStackLocations(error.stack));
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('retrows normal errors untouched', async t => {
|
|
213
|
+
class CustomError extends Error {};
|
|
214
|
+
const originalCustomError1 = new CustomError('This is a custom error');
|
|
215
|
+
const originalCustomError2 = new Error('This is a normal error');
|
|
216
|
+
|
|
217
|
+
const error1 = await t.throwsAsync(runParser(() => {
|
|
218
|
+
throw originalCustomError1;
|
|
219
|
+
}, 'foo', stringParserInputCompanion), {
|
|
220
|
+
instanceOf: CustomError,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
t.is(error1, originalCustomError1);
|
|
224
|
+
|
|
225
|
+
const error2 = await t.throwsAsync(runParser(() => {
|
|
226
|
+
throw originalCustomError2;
|
|
227
|
+
}, 'foo', stringParserInputCompanion), {
|
|
228
|
+
instanceOf: Error,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
t.is(error2, originalCustomError2);
|
|
232
|
+
});
|
|
233
|
+
|
|
185
234
|
test('throws on parserInputCompanion type mismatch', async t => {
|
|
186
235
|
const anythingParser: Parser<any, any> = createArrayParser(createElementParser());
|
|
187
236
|
|
|
@@ -208,9 +257,12 @@ test('thrown error has input reader state', async t => {
|
|
|
208
257
|
yield 'bar';
|
|
209
258
|
})(),
|
|
210
259
|
stringParserInputCompanion,
|
|
260
|
+
{
|
|
261
|
+
errorStack: true,
|
|
262
|
+
},
|
|
211
263
|
),
|
|
212
264
|
{
|
|
213
|
-
instanceOf:
|
|
265
|
+
instanceOf: normalParserErrorModule.ParserParsingInvariantError,
|
|
214
266
|
},
|
|
215
267
|
);
|
|
216
268
|
|
|
@@ -244,10 +296,11 @@ test('thrown error has input reader state', async t => {
|
|
|
244
296
|
|
|
245
297
|
test('runParser throws with remaining input', async t => {
|
|
246
298
|
const parser: Parser<string, string> = createExactSequenceNaiveParser('foo');
|
|
247
|
-
const error = await t.throwsAsync(() => runParser(parser, 'foobar', stringParserInputCompanion), {
|
|
248
|
-
|
|
299
|
+
const error = await t.throwsAsync(async () => runParser(parser, 'foobar', stringParserInputCompanion), {
|
|
300
|
+
any: true,
|
|
301
|
+
name: 'ParserUnexpectedRemainingInputError',
|
|
249
302
|
message: /remaining input/,
|
|
250
|
-
});
|
|
303
|
+
}) as ParserError;
|
|
251
304
|
|
|
252
305
|
t.is(error.position, 3);
|
|
253
306
|
|
|
@@ -270,7 +323,7 @@ test('runParser does not throw without remaining input', async t => {
|
|
|
270
323
|
const parser: Parser<string, string> = createExactSequenceNaiveParser('foo');
|
|
271
324
|
const output = await runParser(parser, 'foo', stringParserInputCompanion);
|
|
272
325
|
|
|
273
|
-
t.
|
|
326
|
+
t.is(output, 'foo');
|
|
274
327
|
});
|
|
275
328
|
|
|
276
329
|
test('runParserWithRemainingInput with remaining input', async t => {
|
|
@@ -283,8 +336,8 @@ test('runParserWithRemainingInput with remaining input', async t => {
|
|
|
283
336
|
} = await runParserWithRemainingInput(parser, 'foobar', stringParserInputCompanion);
|
|
284
337
|
|
|
285
338
|
t.deepEqual(resultRest, {});
|
|
286
|
-
t.
|
|
287
|
-
t.
|
|
339
|
+
t.is(output, 'foo');
|
|
340
|
+
t.is(await stringFromAsyncIterable(remainingInput!), 'bar');
|
|
288
341
|
t.is(position, 3);
|
|
289
342
|
});
|
|
290
343
|
|
|
@@ -292,6 +345,6 @@ test('runParserWithRemainingInput without remaining input', async t => {
|
|
|
292
345
|
const parser: Parser<string, string> = createExactSequenceNaiveParser('foo');
|
|
293
346
|
const { output, remainingInput } = await runParserWithRemainingInput(parser, 'foo', stringParserInputCompanion);
|
|
294
347
|
|
|
295
|
-
t.
|
|
348
|
+
t.is(output, 'foo');
|
|
296
349
|
t.is(remainingInput, undefined);
|
|
297
350
|
});
|
package/src/parser.test.ts.md
CHANGED
|
@@ -16,25 +16,25 @@ Generated by [AVA](https://avajs.dev).
|
|
|
16
16
|
> Snapshot 1
|
|
17
17
|
|
|
18
18
|
`ParserParsingJoinAllError: No union child parser succeeded.␊
|
|
19
|
-
|
|
19
|
+
All child error stacks, indented:␊
|
|
20
20
|
ParserParsingInvariantError: Expected "3", got "C", at [LOCATIONS]␊
|
|
21
21
|
ParserParsingInvariantError: Expected "c", got "C", at [LOCATIONS]␊
|
|
22
22
|
ParserParsingJoinAllError: No disjunction child parser succeeded.␊
|
|
23
|
-
|
|
23
|
+
All child error stacks, indented:␊
|
|
24
24
|
ParserParsingJoinAllError: No union child parser succeeded.␊
|
|
25
|
-
|
|
25
|
+
All child error stacks, indented:␊
|
|
26
26
|
ParserParsingInvariantError: Expected "1", got "f", at [LOCATIONS]␊
|
|
27
27
|
ParserParsingInvariantError: Expected "a", got "f", at [LOCATIONS]␊
|
|
28
28
|
ParserParsingInvariantError: Expected "A", got "f", at [LOCATIONS]␊
|
|
29
|
-
End of child error stacks␊
|
|
29
|
+
End of all child error stacks␊
|
|
30
30
|
at [LOCATIONS]␊
|
|
31
31
|
ParserParsingInvariantError: Expected "2", got "f", at [LOCATIONS]␊
|
|
32
32
|
ParserParsingInvariantError: Expected "b", got "f", at [LOCATIONS]␊
|
|
33
33
|
ParserParsingInvariantError: Expected "B", got "f", at [LOCATIONS]␊
|
|
34
|
-
End of child error stacks␊
|
|
34
|
+
End of all child error stacks␊
|
|
35
35
|
at [LOCATIONS]␊
|
|
36
36
|
ParserParsingInvariantError: Expected "C", got "!", at [LOCATIONS]␊
|
|
37
|
-
End of child error stacks␊
|
|
37
|
+
End of all child error stacks␊
|
|
38
38
|
at [LOCATIONS]`
|
|
39
39
|
|
|
40
40
|
## errorJoinMode: deepest
|
|
@@ -66,3 +66,10 @@ Generated by [AVA](https://avajs.dev).
|
|
|
66
66
|
ParserParsingInvariantError: Expected "C", got "!", at [LOCATIONS]␊
|
|
67
67
|
End of furthest child error stacks␊
|
|
68
68
|
at [LOCATIONS]`
|
|
69
|
+
|
|
70
|
+
## errorJoinMode: none, errorStack: false
|
|
71
|
+
|
|
72
|
+
> Snapshot 1
|
|
73
|
+
|
|
74
|
+
`This stack is intentionally left blank to avoid capture overhead.␊
|
|
75
|
+
If you need a useful stack trace, pass \`errorStack: true\` to \`runParser\`, trading off some performance.`
|
package/src/parser.test.ts.snap
CHANGED
|
Binary file
|
package/src/parser.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { Class } from 'type-fest';
|
|
1
|
+
import { type Class } from 'type-fest';
|
|
2
2
|
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
3
3
|
import { InputReaderImplementation } from './inputReader.js';
|
|
4
4
|
import { type ParserContext, ParserContextImplementation } from './parserContext.js';
|
|
5
5
|
import { type DeriveSequenceElement } from './sequence.js';
|
|
6
|
-
import { ParserError, ParserUnexpectedRemainingInputError } from './parserError.js';
|
|
7
6
|
import { toAsyncIterator } from './toAsyncIterator.js';
|
|
8
7
|
import { inputReaderStateCompanion } from './inputReaderState.js';
|
|
8
|
+
import { isLazyMessageError } from './lazyMessageError.js';
|
|
9
|
+
import { isParserError, isParserParsingFailedError, normalParserErrorModule, noStackCaptureOverheadParserErrorModule, ParserError } from './parserError.js';
|
|
10
|
+
import { NoStackCaptureOverheadError } from './noStackCaptureOverheadError.js';
|
|
11
|
+
import invariant from 'invariant';
|
|
9
12
|
|
|
10
13
|
export type Parser<
|
|
11
14
|
Output,
|
|
@@ -13,6 +16,7 @@ export type Parser<
|
|
|
13
16
|
Element = DeriveSequenceElement<Sequence>,
|
|
14
17
|
> = (parserContext: ParserContext<Sequence, Element>) => Output | Promise<Output>;
|
|
15
18
|
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
20
|
export function getParserName(parser: Parser<any, any, any>, default_ = 'anonymous'): string {
|
|
17
21
|
return parser.name || default_;
|
|
18
22
|
}
|
|
@@ -29,20 +33,17 @@ export function setParserName<
|
|
|
29
33
|
return parser;
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
37
|
const originalParserByClone = new WeakMap<Parser<any, any, any>, Parser<any, any, any>>();
|
|
33
38
|
|
|
34
39
|
export function cloneParser<
|
|
35
40
|
Output,
|
|
36
41
|
Sequence,
|
|
37
42
|
Element = DeriveSequenceElement<Sequence>,
|
|
38
|
-
>(
|
|
39
|
-
parser: Parser<Output, Sequence, Element>,
|
|
40
|
-
): Parser<Output, Sequence, Element> {
|
|
43
|
+
>(parser: Parser<Output, Sequence, Element>): Parser<Output, Sequence, Element> {
|
|
41
44
|
const originalParser = originalParserByClone.get(parser) ?? parser;
|
|
42
45
|
|
|
43
|
-
const clone: Parser<Output, Sequence, Element> =
|
|
44
|
-
return originalParser(parserContext);
|
|
45
|
-
};
|
|
46
|
+
const clone: Parser<Output, Sequence, Element> = parserContext => originalParser(parserContext);
|
|
46
47
|
|
|
47
48
|
setParserName(clone, getParserName(parser));
|
|
48
49
|
|
|
@@ -57,6 +58,7 @@ export type RunParserOptions<
|
|
|
57
58
|
Element = DeriveSequenceElement<Sequence>,
|
|
58
59
|
> = {
|
|
59
60
|
errorJoinMode?: 'none' | 'deepest' | 'furthest' | 'all';
|
|
61
|
+
errorStack?: boolean;
|
|
60
62
|
parserContextClass?: Class<ParserContext<Sequence, Element>>;
|
|
61
63
|
};
|
|
62
64
|
|
|
@@ -82,7 +84,27 @@ async function withEnrichedParserError<
|
|
|
82
84
|
try {
|
|
83
85
|
return await f();
|
|
84
86
|
} catch (error) {
|
|
85
|
-
if (error instanceof
|
|
87
|
+
if (error instanceof NoStackCaptureOverheadError) {
|
|
88
|
+
invariant(
|
|
89
|
+
error.name in normalParserErrorModule,
|
|
90
|
+
'NoStackCaptureOverheadError with unknown name encountered during parser execution: %s',
|
|
91
|
+
error.name,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95
|
+
const normalError: ParserError = new ((normalParserErrorModule as any)[error.name])(error.message);
|
|
96
|
+
Object.assign(normalError, error);
|
|
97
|
+
|
|
98
|
+
normalError.stack = normalError.stack + '\nIf you need a useful stack trace, pass `errorStack: true` to `runParser`, trading off some performance.';
|
|
99
|
+
|
|
100
|
+
error = normalError;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (isLazyMessageError(error)) {
|
|
104
|
+
error.computeMessage();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (isParserError(error)) {
|
|
86
108
|
if (error.position === undefined) {
|
|
87
109
|
error.position = parserContext.position;
|
|
88
110
|
}
|
|
@@ -124,6 +146,7 @@ function runParserInternal<
|
|
|
124
146
|
|
|
125
147
|
const parserContext = new ParserContext<Sequence, Element>(parserInputCompanion, inputReader, undefined, {
|
|
126
148
|
...options,
|
|
149
|
+
errorsModule: options.errorStack ? normalParserErrorModule : noStackCaptureOverheadParserErrorModule,
|
|
127
150
|
debugName: 'root',
|
|
128
151
|
});
|
|
129
152
|
|
|
@@ -158,7 +181,7 @@ export async function runParserWithRemainingInput<
|
|
|
158
181
|
inputReader,
|
|
159
182
|
} = runParserInternal(parser, input, parserInputCompanion, options);
|
|
160
183
|
|
|
161
|
-
return
|
|
184
|
+
return withEnrichedParserError(parserContext, inputReader, async () => {
|
|
162
185
|
const output = await outputPromise;
|
|
163
186
|
|
|
164
187
|
const inputReaderState = inputReader.toInputReaderState();
|
|
@@ -193,13 +216,13 @@ export async function runParser<
|
|
|
193
216
|
inputReader,
|
|
194
217
|
} = runParserInternal(parser, input, parserInputCompanion, options);
|
|
195
218
|
|
|
196
|
-
return
|
|
219
|
+
return withEnrichedParserError(parserContext, inputReader, async () => {
|
|
197
220
|
const output = await outputPromise;
|
|
198
221
|
|
|
199
222
|
const inputReaderState = inputReader.toInputReaderState();
|
|
200
223
|
|
|
201
224
|
if (!inputReaderStateCompanion.isDone(inputReaderState)) {
|
|
202
|
-
throw new ParserUnexpectedRemainingInputError('Unexpected remaining input', 0, parserContext.position);
|
|
225
|
+
throw new normalParserErrorModule.ParserUnexpectedRemainingInputError('Unexpected remaining input', 0, parserContext.position);
|
|
203
226
|
}
|
|
204
227
|
|
|
205
228
|
return output;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createFixedLengthSequenceParser } from
|
|
2
|
-
import { getParserName, Parser, setParserName } from
|
|
1
|
+
import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
|
|
2
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
3
3
|
|
|
4
4
|
export const createParserConsumedSequenceParser = <Output, Sequence>(
|
|
5
5
|
childParser: Parser<Output, Sequence>,
|
|
@@ -20,7 +20,7 @@ export const createParserConsumedSequenceParser = <Output, Sequence>(
|
|
|
20
20
|
const consumedSequenceParser = createFixedLengthSequenceParser<Sequence>(consumedLength);
|
|
21
21
|
const consumedSequence = await consumedSequenceParser(parserContext);
|
|
22
22
|
|
|
23
|
-
return [value, consumedSequence];
|
|
23
|
+
return [ value, consumedSequence ];
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
setParserName(parserConsumedSequenceParser, `parserConsumedSequenceParser(${getParserName(childParser, 'anonymousParserConsumedSequenceParserChild')})`);
|
|
@@ -2,13 +2,15 @@ import test from 'ava';
|
|
|
2
2
|
import { ParserContextImplementation } from './parserContext.js';
|
|
3
3
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
4
4
|
import { InputReaderImplementation } from './inputReader.js';
|
|
5
|
-
import {
|
|
5
|
+
import { noStackCaptureOverheadParserErrorModule } from './parserError.js';
|
|
6
6
|
|
|
7
7
|
const commonParserContextArguments = [
|
|
8
8
|
undefined,
|
|
9
9
|
{
|
|
10
10
|
debugName: 'root',
|
|
11
11
|
errorJoinMode: 'all',
|
|
12
|
+
errorStack: false,
|
|
13
|
+
errorsModule: noStackCaptureOverheadParserErrorModule,
|
|
12
14
|
},
|
|
13
15
|
] as const;
|
|
14
16
|
|
|
@@ -26,7 +28,8 @@ test('parserContext.read', async t => {
|
|
|
26
28
|
t.is(await parserContext.read(5), 'h');
|
|
27
29
|
|
|
28
30
|
await t.throwsAsync(async () => parserContext.read(0), {
|
|
29
|
-
|
|
31
|
+
any: true,
|
|
32
|
+
name: 'ParserUnexpectedEndOfInputError',
|
|
30
33
|
});
|
|
31
34
|
});
|
|
32
35
|
|
|
@@ -49,7 +52,8 @@ test('parserContext.readSequence', async t => {
|
|
|
49
52
|
t.is(await parserContext.readSequence(0, 0), '');
|
|
50
53
|
|
|
51
54
|
await t.throwsAsync(async () => parserContext.readSequence(0, 1), {
|
|
52
|
-
|
|
55
|
+
any: true,
|
|
56
|
+
name: 'ParserUnexpectedEndOfInputError',
|
|
53
57
|
});
|
|
54
58
|
});
|
|
55
59
|
|