@futpib/parser 1.0.0 → 1.0.2
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/build/allSettledStream.js +32 -14
- package/build/allSettledStream.test.js +32 -0
- package/build/androidPackage.d.ts +39 -0
- package/build/androidPackageParser.d.ts +17 -0
- package/build/androidPackageParser.js +183 -0
- package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
- package/build/androidPackageUnparser.d.ts +4 -0
- package/build/androidPackageUnparser.js +90 -0
- package/build/androidPackageUnparser.test.js +26 -0
- package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
- package/build/arbitrarilySlicedAsyncInterable.js +3 -3
- package/build/arbitraryFileSystemEntry.js +1 -1
- package/build/arbitraryZip.d.ts +1 -1
- package/build/arbitraryZip.js +13 -19
- package/build/arbitraryZipPermissions.d.ts +1 -8
- package/build/arbitraryZipPermissions.js +1 -16
- package/build/arbitraryZipStream.d.ts +1 -1
- package/build/arbitraryZipStream.js +3 -3
- package/build/arrayParser.d.ts +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayParser.test.js +4 -4
- package/build/arrayUnparser.d.ts +2 -0
- package/build/arrayUnparser.js +8 -0
- package/build/backsmali.d.ts +1 -0
- package/build/backsmali.js +22 -0
- package/build/bsonParser.js +6 -2
- package/build/bsonParser.test.js +2 -2
- package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
- package/build/{parserInvariant.js → customInvariant.js} +1 -1
- package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
- package/build/dalvikBytecodeParser/formatParsers.js +169 -0
- package/build/dalvikBytecodeParser.d.ts +107 -0
- package/build/dalvikBytecodeParser.js +836 -0
- package/build/dalvikExecutable.d.ts +158 -0
- package/build/dalvikExecutable.js +20 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
- package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
- package/build/dalvikExecutableParser/typeParsers.js +34 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
- package/build/dalvikExecutableParser/typedNumbers.js +19 -0
- package/build/dalvikExecutableParser.d.ts +5 -0
- package/build/dalvikExecutableParser.js +1439 -0
- package/build/dalvikExecutableParser.test.js +70 -0
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
- package/build/debugLogInputParser.d.ts +4 -0
- package/build/debugLogInputParser.js +16 -0
- package/build/debugLogParser.d.ts +1 -1
- package/build/debugLogParser.js +15 -4
- package/build/disjunctionParser.d.ts +2 -1
- package/build/disjunctionParser.js +4 -2
- package/build/elementParser.d.ts +2 -2
- package/build/elementParser.js +1 -1
- package/build/elementTerminatedArrayParser.d.ts +3 -0
- package/build/elementTerminatedArrayParser.js +18 -0
- package/build/elementTerminatedArrayParser.test.js +52 -0
- package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
- package/build/elementTerminatedSequenceArrayParser.js +32 -0
- package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
- package/build/elementTerminatedSequenceParser.d.ts +3 -0
- package/build/elementTerminatedSequenceParser.js +27 -0
- package/build/elementTerminatedSequenceParser.test.js +34 -0
- package/build/endOfInputParser.d.ts +2 -2
- package/build/exactElementParser.d.ts +1 -1
- package/build/exactElementParser.js +10 -5
- package/build/exactSequenceParser.d.ts +2 -1
- package/build/exactSequenceParser.js +12 -2
- package/build/fetchCid.d.ts +1 -0
- package/build/fetchCid.js +107 -0
- package/build/fixedLengthSequenceParser.d.ts +1 -0
- package/build/fixedLengthSequenceParser.js +18 -1
- package/build/fixedLengthSequenceParser.test.js +41 -0
- package/build/hasExecutable.d.ts +1 -0
- package/build/hasExecutable.js +8 -0
- package/build/highResolutionTimer.d.ts +16 -0
- package/build/highResolutionTimer.js +42 -0
- package/build/index.d.ts +5 -2
- package/build/index.js +3 -0
- package/build/inputReader.d.ts +14 -3
- package/build/inputReader.js +43 -6
- package/build/inputReader.test.js +172 -7
- package/build/inputReaderState.d.ts +10 -0
- package/build/inputReaderState.js +16 -0
- package/build/inspect.d.ts +1 -0
- package/build/inspect.js +7 -0
- package/build/javaKeyStoreParser.d.ts +2 -0
- package/build/javaKeyStoreParser.js +67 -0
- package/build/javaKeyStoreParser.test.d.ts +1 -0
- package/build/javaKeyStoreParser.test.js +16 -0
- package/build/jsonParser.d.ts +2 -0
- package/build/jsonParser.js +13 -15
- package/build/jsonParser.test.js +2 -2
- package/build/leb128Parser.d.ts +7 -0
- package/build/leb128Parser.js +82 -0
- package/build/leb128Parser.test.d.ts +1 -0
- package/build/leb128Parser.test.js +107 -0
- package/build/listParser.d.ts +1 -1
- package/build/listParser.js +5 -5
- package/build/lookaheadParser.d.ts +2 -0
- package/build/lookaheadParser.js +14 -0
- package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
- package/build/negativeLookaheadParser.js +24 -0
- package/build/negativeLookaheadParser.test.d.ts +1 -0
- package/build/negativeLookaheadParser.test.js +30 -0
- package/build/nonEmptyArrayParser.d.ts +2 -0
- package/build/nonEmptyArrayParser.js +32 -0
- package/build/nonEmptyArrayParser.test.d.ts +1 -0
- package/build/nonEmptyArrayParser.test.js +16 -0
- package/build/optionalParser.d.ts +1 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +13 -4
- package/build/parser.js +67 -32
- package/build/parser.test.js +94 -27
- package/build/parserAccessorParser.d.ts +1 -1
- package/build/parserAccessorParser.js +9 -1
- package/build/parserConsumedSequenceParser.d.ts +2 -0
- package/build/parserConsumedSequenceParser.js +22 -0
- package/build/parserContext.d.ts +20 -6
- package/build/parserContext.js +70 -40
- package/build/parserContext.test.js +34 -7
- package/build/parserCreatorCompose.d.ts +4 -3
- package/build/parserCreatorCompose.js +9 -3
- package/build/parserError.d.ts +6 -0
- package/build/parserError.js +6 -6
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.d.ts +35 -0
- package/build/parserInputCompanion.js +68 -0
- package/build/promiseCompose.d.ts +1 -1
- package/build/promiseCompose.js +12 -1
- package/build/promiseSettled.d.ts +1 -0
- package/build/promiseSettled.js +4 -0
- package/build/quantifierParser.d.ts +2 -0
- package/build/quantifierParser.js +17 -0
- package/build/separatedArrayParser.d.ts +2 -0
- package/build/separatedArrayParser.js +39 -0
- package/build/separatedArrayParser.test.d.ts +1 -0
- package/build/separatedArrayParser.test.js +21 -0
- package/build/sequenceBuffer.d.ts +13 -3
- package/build/sequenceBuffer.js +60 -8
- package/build/sequenceBuffer.test.js +59 -2
- package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
- package/build/sequenceTerminatedSequenceParser.js +32 -0
- package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
- package/build/sequenceTerminatedSequenceParser.test.js +37 -0
- package/build/sequenceUnparser.d.ts +2 -0
- package/build/sequenceUnparser.js +6 -0
- package/build/skipParser.d.ts +1 -1
- package/build/skipParser.js +4 -2
- package/build/skipToParser.d.ts +2 -0
- package/build/skipToParser.js +11 -0
- package/build/sliceBoundedParser.d.ts +2 -2
- package/build/sliceBoundedParser.js +8 -3
- package/build/sliceBoundedParser.test.js +37 -3
- package/build/smali.d.ts +1 -0
- package/build/smali.js +17 -0
- package/build/smaliParser.d.ts +12 -0
- package/build/smaliParser.js +656 -0
- package/build/smaliParser.test.d.ts +1 -0
- package/build/smaliParser.test.js +115 -0
- package/build/terminatedArrayParser.d.ts +4 -2
- package/build/terminatedArrayParser.js +82 -5
- package/build/terminatedArrayParser.test.d.ts +1 -0
- package/build/terminatedArrayParser.test.js +131 -0
- package/build/toAsyncIterable.d.ts +1 -0
- package/build/toAsyncIterable.js +7 -0
- package/build/toAsyncIterator.d.ts +1 -0
- package/build/toAsyncIterator.js +33 -0
- package/build/tupleParser.d.ts +4 -0
- package/build/tupleParser.js +1 -5
- package/build/uint8Array.d.ts +1 -0
- package/build/uint8Array.js +7 -0
- package/build/unionParser.d.ts +2 -1
- package/build/unionParser.js +27 -12
- package/build/unionParser.test.d.ts +1 -0
- package/build/unionParser.test.js +60 -0
- package/build/unparser.d.ts +8 -0
- package/build/unparser.js +104 -0
- package/build/unparser.test.d.ts +1 -0
- package/build/unparser.test.js +150 -0
- package/build/unparserContext.d.ts +31 -0
- package/build/unparserContext.js +74 -0
- package/build/unparserError.d.ts +9 -0
- package/build/unparserError.js +9 -0
- package/build/unparserImplementationInvariant.d.ts +2 -0
- package/build/unparserImplementationInvariant.js +5 -0
- package/build/unparserOutputCompanion.d.ts +15 -0
- package/build/unparserOutputCompanion.js +13 -0
- package/build/zip.d.ts +9 -17
- package/build/zipParser.d.ts +20 -12
- package/build/zipParser.js +83 -71
- package/build/zipParser.test.js +2 -7
- package/build/zipUnparser.d.ts +8 -0
- package/build/zipUnparser.js +200 -0
- package/build/zipUnparser.test.d.ts +1 -0
- package/build/zipUnparser.test.js +80 -0
- package/package.json +26 -8
- package/src/allSettledStream.test.ts +40 -0
- package/src/allSettledStream.ts +47 -15
- package/src/androidPackage.ts +48 -0
- package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
- package/src/androidPackageParser.test.ts.md +271 -0
- package/src/androidPackageParser.test.ts.snap +0 -0
- package/src/androidPackageParser.ts +440 -0
- package/src/androidPackageUnparser.test.ts +36 -0
- package/src/androidPackageUnparser.ts +120 -0
- package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
- package/src/arbitraryFileSystemEntry.ts +2 -4
- package/src/arbitraryZip.ts +20 -27
- package/src/arbitraryZipPermissions.ts +0 -25
- package/src/arbitraryZipStream.ts +4 -4
- package/src/arrayParser.test.ts +4 -4
- package/src/arrayParser.ts +3 -2
- package/src/arrayUnparser.ts +13 -0
- package/src/backsmali.ts +30 -0
- package/src/bsonParser.test.ts +2 -2
- package/src/bsonParser.ts +16 -5
- package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
- package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
- package/src/dalvikBytecodeParser.ts +2074 -0
- package/src/dalvikExecutable.ts +220 -0
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
- package/src/dalvikExecutableParser/typeParsers.ts +65 -0
- package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
- package/src/dalvikExecutableParser.test.ts +89 -0
- package/src/dalvikExecutableParser.test.ts.md +634 -0
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +2768 -0
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
- package/src/debugLogInputParser.ts +28 -0
- package/src/debugLogParser.ts +20 -4
- package/src/disjunctionParser.ts +10 -5
- package/src/elementParser.ts +3 -3
- package/src/elementTerminatedArrayParser.test.ts +99 -0
- package/src/elementTerminatedArrayParser.ts +31 -0
- package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
- package/src/elementTerminatedSequenceArrayParser.ts +52 -0
- package/src/elementTerminatedSequenceParser.test.ts +54 -0
- package/src/elementTerminatedSequenceParser.ts +43 -0
- package/src/endOfInputParser.ts +4 -4
- package/src/exactElementParser.ts +18 -12
- package/src/exactSequenceParser.ts +24 -3
- package/src/fetchCid.ts +125 -0
- package/src/fixedLengthSequenceParser.test.ts +77 -0
- package/src/fixedLengthSequenceParser.ts +28 -1
- package/src/hasExecutable.ts +11 -0
- package/src/highResolutionTimer.ts +49 -0
- package/src/index.ts +15 -2
- package/src/inputReader.test.ts +216 -7
- package/src/inputReader.ts +80 -5
- package/src/inputReaderState.ts +33 -0
- package/src/inspect.ts +9 -0
- package/src/javaKeyStore.ts +0 -0
- package/src/javaKeyStoreParser.test.ts +22 -0
- package/src/javaKeyStoreParser.test.ts.md +103 -0
- package/src/javaKeyStoreParser.test.ts.snap +0 -0
- package/src/javaKeyStoreParser.ts +136 -0
- package/src/jsonParser.test.ts +2 -2
- package/src/jsonParser.ts +23 -34
- package/src/leb128Parser.test.ts +171 -0
- package/src/leb128Parser.ts +125 -0
- package/src/listParser.ts +6 -6
- package/src/lookaheadParser.ts +19 -0
- package/src/negativeLookaheadParser.test.ts +53 -0
- package/src/negativeLookaheadParser.ts +36 -0
- package/src/nonEmptyArrayParser.test.ts +20 -0
- package/src/nonEmptyArrayParser.ts +44 -0
- package/src/optionalParser.ts +4 -3
- package/src/parser.test.ts +148 -27
- package/src/parser.test.ts.md +21 -21
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +153 -49
- package/src/parserAccessorParser.ts +12 -2
- package/src/parserConsumedSequenceParser.ts +29 -0
- package/src/parserContext.test.ts +38 -7
- package/src/parserContext.ts +127 -51
- package/src/parserCreatorCompose.ts +25 -7
- package/src/parserError.ts +9 -6
- package/src/parserImplementationInvariant.ts +2 -2
- package/src/parserInputCompanion.ts +102 -0
- package/src/promiseCompose.ts +17 -3
- package/src/promiseSettled.ts +6 -0
- package/src/quantifierParser.ts +25 -0
- package/src/separatedArrayParser.test.ts +34 -0
- package/src/separatedArrayParser.ts +55 -0
- package/src/sequenceBuffer.test.ts +72 -2
- package/src/sequenceBuffer.ts +93 -7
- package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
- package/src/sequenceTerminatedSequenceParser.ts +62 -0
- package/src/sequenceUnparser.ts +9 -0
- package/src/skipParser.ts +7 -5
- package/src/skipToParser.ts +16 -0
- package/src/sliceBoundedParser.test.ts +45 -3
- package/src/sliceBoundedParser.ts +21 -3
- package/src/smali.ts +24 -0
- package/src/smaliParser.test.ts +132 -0
- package/src/smaliParser.test.ts.md +2320 -0
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +1166 -0
- package/src/terminatedArrayParser.test.ts +258 -0
- package/src/terminatedArrayParser.ts +111 -6
- package/src/toAsyncIterable.ts +7 -0
- package/src/toAsyncIterator.ts +48 -0
- package/src/tupleParser.ts +8 -5
- package/src/uint8Array.ts +10 -0
- package/src/unionParser.test.ts +79 -0
- package/src/unionParser.ts +44 -16
- package/src/unparser.test.ts +221 -0
- package/src/unparser.ts +209 -0
- package/src/unparserContext.ts +127 -0
- package/src/unparserError.ts +12 -0
- package/src/unparserImplementationInvariant.ts +6 -0
- package/src/unparserOutputCompanion.ts +24 -0
- package/src/zip.ts +10 -22
- package/src/zipParser.test.ts +2 -8
- package/src/zipParser.ts +223 -146
- package/src/zipUnparser.test.ts +119 -0
- package/src/zipUnparser.ts +300 -0
- package/build/apk.d.ts +0 -13
- package/build/apkParser.d.ts +0 -3
- package/build/apkParser.js +0 -135
- package/build/arbitraryDosDate.d.ts +0 -2
- package/build/arbitraryDosDate.js +0 -8
- package/build/arbitraryZipEntry.d.ts +0 -3
- package/build/arbitraryZipEntry.js +0 -26
- package/build/createDisjunctionParser.d.ts +0 -2
- package/build/createDisjunctionParser.js +0 -47
- package/build/createExactParser.d.ts +0 -2
- package/build/createExactParser.js +0 -12
- package/build/createSequentialUnionParser.d.ts +0 -2
- package/build/createSequentialUnionParser.js +0 -69
- package/build/fixedLengthChunkParser.d.ts +0 -2
- package/build/fixedLengthChunkParser.js +0 -12
- package/build/fixedLengthParser.d.ts +0 -2
- package/build/fixedLengthParser.js +0 -12
- package/build/inputChunkBuffer.d.ts +0 -15
- package/build/inputChunkBuffer.js +0 -40
- package/build/inputChunkBuffer.test.js +0 -34
- package/build/inputCompanion.d.ts +0 -18
- package/build/inputCompanion.js +0 -28
- package/build/invariantDefined.d.ts +0 -1
- package/build/invariantDefined.js +0 -5
- package/build/invariantIdentity.d.ts +0 -3
- package/build/invariantIdentity.js +0 -5
- package/build/jsonParser2.d.ts +0 -3
- package/build/jsonParser2.js +0 -52
- package/build/jsonParser2.test.js +0 -22
- package/build/negativeLookahead.js +0 -20
- package/build/parserCompose.d.ts +0 -3
- package/build/parserCompose.js +0 -7
- package/build/parserImplementationInvariantInvariant.d.ts +0 -3
- package/build/parserImplementationInvariantInvariant.js +0 -15
- package/build/promiseFish.d.ts +0 -1
- package/build/promiseFish.js +0 -3
- package/build/sequenceParser.d.ts +0 -3
- package/build/sequenceParser.js +0 -10
- package/build/terminatedSequenceParser.d.ts +0 -2
- package/build/terminatedSequenceParser.js +0 -24
- package/build/zipEntry.d.ts +0 -28
- package/build/zipFile.d.ts +0 -32
- package/build/zipFileEntry.d.ts +0 -6
- package/src/apk.ts +0 -16
- package/src/apkParser.test.ts.md +0 -268
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +0 -327
- package/src/inputCompanion.ts +0 -43
- package/src/invariantDefined.ts +0 -6
- package/src/invariantIdentity.ts +0 -8
- package/src/negativeLookahead.ts +0 -26
- /package/build/{apk.js → androidPackage.js} +0 -0
- /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
- /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
- /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
- /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
- /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
- /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
3
|
+
import { getParserName, runParser } from './parser.js';
|
|
4
|
+
import { fetchCid } from './fetchCid.js';
|
|
5
|
+
import { smaliAnnotationParser, smaliCodeParameterParser, smaliFieldParser, smaliParser } from './smaliParser.js';
|
|
6
|
+
import { hasExecutable } from './hasExecutable.js';
|
|
7
|
+
import { baksmaliClass } from './backsmali.js';
|
|
8
|
+
const hasBaksmaliPromise = hasExecutable('baksmali');
|
|
9
|
+
function stringParserTest(parser, examples) {
|
|
10
|
+
const parserName = getParserName(parser);
|
|
11
|
+
for (const [input, expected] of examples) {
|
|
12
|
+
test(parserName + ' ' + JSON.stringify(input), async (t) => {
|
|
13
|
+
const actual = await runParser(parser, input, stringParserInputCompanion, {
|
|
14
|
+
errorJoinMode: 'all',
|
|
15
|
+
});
|
|
16
|
+
t.deepEqual(actual, expected);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
stringParserTest(smaliCodeParameterParser, [
|
|
21
|
+
[
|
|
22
|
+
' .param p1\n',
|
|
23
|
+
{
|
|
24
|
+
index: 1,
|
|
25
|
+
prefix: 'p',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
' .param p1, "savedInstanceState" # Landroid/os/Bundle;\n',
|
|
30
|
+
{
|
|
31
|
+
index: 1,
|
|
32
|
+
prefix: 'p',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
]);
|
|
36
|
+
stringParserTest(smaliFieldParser, [
|
|
37
|
+
[
|
|
38
|
+
'.field private barcodeScannerView:Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;\n',
|
|
39
|
+
{
|
|
40
|
+
accessFlags: {
|
|
41
|
+
abstract: false,
|
|
42
|
+
annotation: false,
|
|
43
|
+
bridge: false,
|
|
44
|
+
constructor: false,
|
|
45
|
+
declaredSynchronized: false,
|
|
46
|
+
enum: false,
|
|
47
|
+
final: false,
|
|
48
|
+
interface: false,
|
|
49
|
+
native: false,
|
|
50
|
+
private: true,
|
|
51
|
+
protected: false,
|
|
52
|
+
public: false,
|
|
53
|
+
static: false,
|
|
54
|
+
strict: false,
|
|
55
|
+
synchronized: false,
|
|
56
|
+
synthetic: false,
|
|
57
|
+
transient: false,
|
|
58
|
+
varargs: false,
|
|
59
|
+
volatile: false,
|
|
60
|
+
},
|
|
61
|
+
field: {
|
|
62
|
+
class: 'FILLED_LATER',
|
|
63
|
+
name: 'barcodeScannerView',
|
|
64
|
+
type: 'Lcom/journeyapps/barcodescanner/DecoratedBarcodeView;',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
]);
|
|
69
|
+
stringParserTest(smaliAnnotationParser, [
|
|
70
|
+
[
|
|
71
|
+
` .annotation system Ldalvik/annotation/Signature;
|
|
72
|
+
value = {
|
|
73
|
+
"<T:",
|
|
74
|
+
"Landroid/view/View;",
|
|
75
|
+
">(I)TT;"
|
|
76
|
+
}
|
|
77
|
+
.end annotation
|
|
78
|
+
`,
|
|
79
|
+
{
|
|
80
|
+
type: 'Ldalvik/annotation/Signature;',
|
|
81
|
+
value: [
|
|
82
|
+
'<T:',
|
|
83
|
+
'Landroid/view/View;',
|
|
84
|
+
'>(I)TT;',
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
]);
|
|
89
|
+
for (const [dexCid, smaliFilePath, shouldSnapshot] of [
|
|
90
|
+
['bafkreibb4gsprc3fvmnyqx6obswvm7e7wngnfj64gz65ey72r7xgyzymt4', 'pl/czak/minimal/MainActivity', true],
|
|
91
|
+
['bafybeiebe27ylo53trgitu6fqfbmba43c4ivxj3nt4kumsilkucpbdxtqq', 'd/m', true],
|
|
92
|
+
// [ 'bafybeibbupm7uzhuq4pa674rb2amxsenbdaoijigmaf4onaodaql4mh7yy', 'com/journeyapps/barcodescanner/CaptureActivity', true ],
|
|
93
|
+
// [ 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda', false ],
|
|
94
|
+
]) {
|
|
95
|
+
test.serial('smali from dex ' + dexCid + ' ' + smaliFilePath, async (t) => {
|
|
96
|
+
const hasBaksmali = await hasBaksmaliPromise;
|
|
97
|
+
if (!hasBaksmali) {
|
|
98
|
+
t.pass('skipping test because baksmali is not available');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const dexStream = await fetchCid(dexCid);
|
|
102
|
+
const smali = await baksmaliClass(dexStream, smaliFilePath);
|
|
103
|
+
const actual = await runParser(smaliParser, smali, stringParserInputCompanion, {
|
|
104
|
+
errorJoinMode: 'all',
|
|
105
|
+
});
|
|
106
|
+
// console.dir(actual, { depth: null });
|
|
107
|
+
if (shouldSnapshot) {
|
|
108
|
+
t.snapshot(actual);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
//console.dir(actual, { depth: null });
|
|
112
|
+
t.pass();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import { Parser } from
|
|
2
|
-
export declare const
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
|
+
export declare const createTerminatedArrayParserNaive: <ElementOutput, TerminatorOutput, Sequence>(elementParser: Parser<ElementOutput, Sequence>, terminatorParser: Parser<TerminatorOutput, Sequence>) => Parser<[ElementOutput[], TerminatorOutput], Sequence>;
|
|
3
|
+
export declare const createTerminatedArrayParser: <ElementOutput, TerminatorOutput, Sequence>(elementParser: Parser<ElementOutput, Sequence>, terminatorParser: Parser<TerminatorOutput, Sequence>) => Parser<[ElementOutput[], TerminatorOutput], Sequence>;
|
|
4
|
+
export declare const createTerminatedArrayParserUnsafe: <ElementOutput, TerminatorOutput, Sequence>(elementParser: Parser<ElementOutput, Sequence>, terminatorParser: Parser<TerminatorOutput, Sequence>) => Parser<[ElementOutput[], TerminatorOutput], Sequence>;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { getParserName, setParserName } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
|
+
import { parserImplementationInvariant } from './parserImplementationInvariant.js';
|
|
4
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
5
|
+
import { createUnionParser } from './unionParser.js';
|
|
4
6
|
class Terminated {
|
|
5
7
|
value;
|
|
6
8
|
constructor(value) {
|
|
7
9
|
this.value = value;
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
|
-
export const
|
|
12
|
+
export const createTerminatedArrayParserNaive = (elementParser, terminatorParser) => {
|
|
11
13
|
const wrappedTerminatorParser = promiseCompose(terminatorParser, terminatorValue => new Terminated(terminatorValue));
|
|
12
14
|
setParserName(wrappedTerminatorParser, getParserName(terminatorParser, 'anonymousTerminator'));
|
|
13
15
|
const elementOrTerminatorParser = createUnionParser([
|
|
14
16
|
elementParser,
|
|
15
17
|
promiseCompose(terminatorParser, terminatorValue => new Terminated(terminatorValue)),
|
|
16
18
|
]);
|
|
17
|
-
|
|
19
|
+
const terminatedArrayParserNaive = async (parserContext) => {
|
|
18
20
|
const elements = [];
|
|
19
21
|
while (true) {
|
|
20
22
|
const elementOrTerminator = await elementOrTerminatorParser(parserContext);
|
|
@@ -24,4 +26,79 @@ export const createTerminatedArrayParser = (elementParser, terminatorParser) =>
|
|
|
24
26
|
elements.push(elementOrTerminator);
|
|
25
27
|
}
|
|
26
28
|
};
|
|
29
|
+
setParserName(terminatedArrayParserNaive, `${getParserName(elementParser, 'anonymousElement')}*?${getParserName(terminatorParser, 'anonymousTerminator')}`);
|
|
30
|
+
return terminatedArrayParserNaive;
|
|
31
|
+
};
|
|
32
|
+
export const createTerminatedArrayParser = (elementParser, terminatorParser) => {
|
|
33
|
+
const terminatedArrayParser = async (parserContext) => {
|
|
34
|
+
const elements = [];
|
|
35
|
+
while (true) {
|
|
36
|
+
const terminatorParserContext = parserContext.lookahead({
|
|
37
|
+
debugName: getParserName(terminatorParser, 'anonymousTerminator'),
|
|
38
|
+
});
|
|
39
|
+
try {
|
|
40
|
+
const terminatorValue = await terminatorParser(terminatorParserContext);
|
|
41
|
+
const elementParserContext = parserContext.lookahead({
|
|
42
|
+
debugName: getParserName(elementParser, 'anonymousElement'),
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
await elementParser(elementParserContext);
|
|
46
|
+
parserImplementationInvariant(false, [
|
|
47
|
+
'Both element and terminator parsers matched.',
|
|
48
|
+
'Element parser: %s',
|
|
49
|
+
'Terminator parser: %s',
|
|
50
|
+
], getParserName(elementParser, 'anonymousElement'), getParserName(terminatorParser, 'anonymousTerminator'));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (!(error instanceof ParserParsingFailedError)) {
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
elementParserContext.dispose();
|
|
59
|
+
}
|
|
60
|
+
terminatorParserContext.unlookahead();
|
|
61
|
+
return [elements, terminatorValue];
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (!(error instanceof ParserParsingFailedError)) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
terminatorParserContext.dispose();
|
|
70
|
+
}
|
|
71
|
+
const element = await elementParser(parserContext);
|
|
72
|
+
elements.push(element);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
setParserName(terminatedArrayParser, `${getParserName(elementParser, 'anonymousElement')}*?${getParserName(terminatorParser, 'anonymousTerminator')}`);
|
|
76
|
+
return terminatedArrayParser;
|
|
77
|
+
};
|
|
78
|
+
export const createTerminatedArrayParserUnsafe = (elementParser, terminatorParser) => {
|
|
79
|
+
const terminatedArrayParserUnsafe = async (parserContext) => {
|
|
80
|
+
const elements = [];
|
|
81
|
+
while (true) {
|
|
82
|
+
const terminatorParserContext = parserContext.lookahead({
|
|
83
|
+
debugName: getParserName(terminatorParser, 'anonymousTerminator'),
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
const terminatorValue = await terminatorParser(terminatorParserContext);
|
|
87
|
+
terminatorParserContext.unlookahead();
|
|
88
|
+
return [elements, terminatorValue];
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (!(error instanceof ParserParsingFailedError)) {
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
terminatorParserContext.dispose();
|
|
97
|
+
}
|
|
98
|
+
const element = await elementParser(parserContext);
|
|
99
|
+
elements.push(element);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
setParserName(terminatedArrayParserUnsafe, `${getParserName(elementParser, 'anonymousElement')}*?${getParserName(terminatorParser, 'anonymousTerminator')}`);
|
|
103
|
+
return terminatedArrayParserUnsafe;
|
|
27
104
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import * as fc from 'fast-check';
|
|
3
|
+
import { testProp } from '@fast-check/ava';
|
|
4
|
+
import { createTerminatedArrayParser, createTerminatedArrayParserNaive, createTerminatedArrayParserUnsafe } from './terminatedArrayParser.js';
|
|
5
|
+
import { runParser } from './parser.js';
|
|
6
|
+
import { stringParserInputCompanion, uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
7
|
+
import { HighResolutionTotalTimer } from './highResolutionTimer.js';
|
|
8
|
+
import { createElementParser } from './elementParser.js';
|
|
9
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
10
|
+
import { createTupleParser } from './tupleParser.js';
|
|
11
|
+
import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
12
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
13
|
+
import { createUnionParser } from './unionParser.js';
|
|
14
|
+
import { createExactElementParser } from './exactElementParser.js';
|
|
15
|
+
test('terminatedArrayParser of union parsers', async (t) => {
|
|
16
|
+
const parser = createTerminatedArrayParser(createUnionParser([
|
|
17
|
+
createExactElementParser(1),
|
|
18
|
+
createExactElementParser(2),
|
|
19
|
+
]), createExactElementParser(0));
|
|
20
|
+
const input = new Uint8Array([0]);
|
|
21
|
+
const result = await runParser(parser, input, uint8ArrayParserInputCompanion);
|
|
22
|
+
t.deepEqual(result, [[], 0]);
|
|
23
|
+
});
|
|
24
|
+
testProp('terminatedArrayParser both terminator and element matching', [
|
|
25
|
+
fc.string(),
|
|
26
|
+
], async (t, string) => {
|
|
27
|
+
const terminatedArrayParserNaive = createTerminatedArrayParserNaive(createExactSequenceParser(string), createExactSequenceParser(string));
|
|
28
|
+
const terminatedArrayParser = createTerminatedArrayParser(createExactSequenceParser(string), createExactSequenceParser(string));
|
|
29
|
+
const [naiveResult, result,] = await Promise.allSettled([
|
|
30
|
+
runParser(terminatedArrayParserNaive, string, stringParserInputCompanion),
|
|
31
|
+
runParser(terminatedArrayParser, string, stringParserInputCompanion),
|
|
32
|
+
]);
|
|
33
|
+
t.is(naiveResult.status, 'rejected');
|
|
34
|
+
if (result.status === 'rejected'
|
|
35
|
+
&& naiveResult.status === 'rejected') {
|
|
36
|
+
result.reason.message = 'REDACTED';
|
|
37
|
+
naiveResult.reason.message = 'REDACTED';
|
|
38
|
+
}
|
|
39
|
+
t.deepEqual(result, naiveResult);
|
|
40
|
+
}, {
|
|
41
|
+
verbose: true,
|
|
42
|
+
});
|
|
43
|
+
const naiveTotalTimer = new HighResolutionTotalTimer();
|
|
44
|
+
const optimizedTotalTimer = new HighResolutionTotalTimer();
|
|
45
|
+
const unsafeTotalTimer = new HighResolutionTotalTimer();
|
|
46
|
+
testProp.serial('terminatedArrayParser', [
|
|
47
|
+
fc
|
|
48
|
+
.integer({
|
|
49
|
+
min: 1,
|
|
50
|
+
max: 2 ** 8,
|
|
51
|
+
})
|
|
52
|
+
.chain(terminatorLength => (fc
|
|
53
|
+
.string({
|
|
54
|
+
minLength: terminatorLength,
|
|
55
|
+
})
|
|
56
|
+
.map(string => ({
|
|
57
|
+
string,
|
|
58
|
+
terminator: string.slice(0 - terminatorLength)
|
|
59
|
+
}))
|
|
60
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2)))
|
|
61
|
+
], async (t, { string, terminator }) => {
|
|
62
|
+
const terminatedArrayParserNaive = createTerminatedArrayParserNaive(promiseCompose(createTupleParser([
|
|
63
|
+
createNegativeLookaheadParser(createExactSequenceParser(terminator)),
|
|
64
|
+
createElementParser(),
|
|
65
|
+
]), ([_, element]) => element), createExactSequenceParser(terminator));
|
|
66
|
+
const terminatedArrayParser = createTerminatedArrayParser(promiseCompose(createTupleParser([
|
|
67
|
+
createNegativeLookaheadParser(createExactSequenceParser(terminator)),
|
|
68
|
+
createElementParser(),
|
|
69
|
+
]), ([_, element]) => element), createExactSequenceParser(terminator));
|
|
70
|
+
const createTestWrapperParser = (innerParser) => async (parserContext) => {
|
|
71
|
+
const [characters, terminator] = await innerParser(parserContext);
|
|
72
|
+
return {
|
|
73
|
+
string: characters.join(''),
|
|
74
|
+
terminator,
|
|
75
|
+
nextPeek: await parserContext.peek(0),
|
|
76
|
+
position: parserContext.position,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const actualNaive = await naiveTotalTimer.measureAsync(() => runParser(createTestWrapperParser(terminatedArrayParserNaive), string, stringParserInputCompanion));
|
|
80
|
+
t.is(actualNaive.string.length + actualNaive.terminator.length, string.length);
|
|
81
|
+
const actual = await optimizedTotalTimer.measureAsync(() => runParser(createTestWrapperParser(terminatedArrayParser), string, stringParserInputCompanion));
|
|
82
|
+
t.deepEqual(actual, actualNaive);
|
|
83
|
+
}, {
|
|
84
|
+
verbose: true,
|
|
85
|
+
});
|
|
86
|
+
test.serial('terminatedArrayParser performance', t => {
|
|
87
|
+
t.true(optimizedTotalTimer.time * 1n < naiveTotalTimer.time, `Naive: ${naiveTotalTimer.time / 1000000n}ms, Optimized: ${optimizedTotalTimer.time / 1000000n}ms`);
|
|
88
|
+
});
|
|
89
|
+
testProp.serial('terminatedArrayParserUnsafe', [
|
|
90
|
+
fc
|
|
91
|
+
.integer({
|
|
92
|
+
min: 1,
|
|
93
|
+
max: 2 ** 8,
|
|
94
|
+
})
|
|
95
|
+
.chain(terminatorLength => (fc
|
|
96
|
+
.string({
|
|
97
|
+
minLength: terminatorLength,
|
|
98
|
+
})
|
|
99
|
+
.map(string => ({
|
|
100
|
+
string,
|
|
101
|
+
terminator: string.slice(0 - terminatorLength)
|
|
102
|
+
}))
|
|
103
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2)))
|
|
104
|
+
], async (t, { string, terminator }) => {
|
|
105
|
+
const terminatedArrayParserNaive = createTerminatedArrayParserNaive(promiseCompose(createTupleParser([
|
|
106
|
+
createNegativeLookaheadParser(createExactSequenceParser(terminator)),
|
|
107
|
+
createElementParser(),
|
|
108
|
+
]), ([_, element]) => element), createExactSequenceParser(terminator));
|
|
109
|
+
const terminatedArrayParserUnsafe = createTerminatedArrayParserUnsafe(promiseCompose(createTupleParser([
|
|
110
|
+
createNegativeLookaheadParser(createExactSequenceParser(terminator)),
|
|
111
|
+
createElementParser(),
|
|
112
|
+
]), ([_, element]) => element), createExactSequenceParser(terminator));
|
|
113
|
+
const createTestWrapperParser = (innerParser) => async (parserContext) => {
|
|
114
|
+
const [characters, terminator] = await innerParser(parserContext);
|
|
115
|
+
return {
|
|
116
|
+
string: characters.join(''),
|
|
117
|
+
terminator,
|
|
118
|
+
nextPeek: await parserContext.peek(0),
|
|
119
|
+
position: parserContext.position,
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
const actualNaive = await runParser(createTestWrapperParser(terminatedArrayParserNaive), string, stringParserInputCompanion);
|
|
123
|
+
t.is(actualNaive.string.length + actualNaive.terminator.length, string.length);
|
|
124
|
+
const actual = await unsafeTotalTimer.measureAsync(() => runParser(createTestWrapperParser(terminatedArrayParserUnsafe), string, stringParserInputCompanion));
|
|
125
|
+
t.deepEqual(actual, actualNaive);
|
|
126
|
+
}, {
|
|
127
|
+
verbose: true,
|
|
128
|
+
});
|
|
129
|
+
test.serial('terminatedArrayParserUnsafe performance', t => {
|
|
130
|
+
t.true(unsafeTotalTimer.time * 1n < naiveTotalTimer.time, `Naive: ${naiveTotalTimer.time / 1000000n}ms, Unsafe: ${unsafeTotalTimer.time / 1000000n}ms`);
|
|
131
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toAsyncIterable<T>(value: AsyncIterator<T>): AsyncIterable<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toAsyncIterator<T>(value: AsyncIterator<T> | AsyncIterable<T> | Iterable<T> | T): AsyncIterator<T>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import invariant from "invariant";
|
|
2
|
+
function isAsyncIterable(value) {
|
|
3
|
+
return value && typeof value[Symbol.asyncIterator] === 'function';
|
|
4
|
+
}
|
|
5
|
+
function isIterable(value) {
|
|
6
|
+
return value && typeof value[Symbol.iterator] === 'function';
|
|
7
|
+
}
|
|
8
|
+
function isIterator(value) {
|
|
9
|
+
return value && typeof value.next === 'function';
|
|
10
|
+
}
|
|
11
|
+
function iteratorToAsyncIterator(iterator) {
|
|
12
|
+
return {
|
|
13
|
+
next: async () => iterator.next(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function toAsyncIterator(value) {
|
|
17
|
+
if (typeof value === 'string'
|
|
18
|
+
|| value instanceof Uint8Array) {
|
|
19
|
+
return (async function* () {
|
|
20
|
+
yield value;
|
|
21
|
+
})();
|
|
22
|
+
}
|
|
23
|
+
if (isAsyncIterable(value)) {
|
|
24
|
+
return value[Symbol.asyncIterator]();
|
|
25
|
+
}
|
|
26
|
+
if (isIterable(value)) {
|
|
27
|
+
return iteratorToAsyncIterator(value[Symbol.iterator]());
|
|
28
|
+
}
|
|
29
|
+
if (isIterator(value)) {
|
|
30
|
+
return iteratorToAsyncIterator(value);
|
|
31
|
+
}
|
|
32
|
+
invariant(false, 'Value must be an async iterator, async iterable, iterable or iterator got %s.', value);
|
|
33
|
+
}
|
package/build/tupleParser.d.ts
CHANGED
|
@@ -9,3 +9,7 @@ export declare function createTupleParser<A, B, C, D, E, F, G, H, Sequence>([par
|
|
|
9
9
|
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I], Sequence>;
|
|
10
10
|
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J], Sequence>;
|
|
11
11
|
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K], Sequence>;
|
|
12
|
+
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L], Sequence>;
|
|
13
|
+
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M], Sequence>;
|
|
14
|
+
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, N, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM, parserN]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>, Parser<N, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M, N], Sequence>;
|
|
15
|
+
export declare function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, Sequence>([parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM, parserN, parserO]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>, Parser<N, Sequence>, Parser<O, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O], Sequence>;
|
package/build/tupleParser.js
CHANGED
|
@@ -8,10 +8,6 @@ export function createTupleParser(parsers) {
|
|
|
8
8
|
}
|
|
9
9
|
return values;
|
|
10
10
|
};
|
|
11
|
-
setParserName(tupleParser,
|
|
12
|
-
'[',
|
|
13
|
-
parsers.map(parser => getParserName(parser, 'anonymousTupleChild')).join(','),
|
|
14
|
-
']',
|
|
15
|
-
].join(''));
|
|
11
|
+
setParserName(tupleParser, parsers.map(parser => '(' + getParserName(parser, 'anonymousTupleChild') + ')').join(''));
|
|
16
12
|
return tupleParser;
|
|
17
13
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uint8ArrayAsyncIterableToUint8Array(uint8ArrayAsyncIterable: AsyncIterable<Uint8Array> | Iterable<Uint8Array>): Promise<Uint8Array>;
|
package/build/unionParser.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { type Parser } from './parser.js';
|
|
2
|
-
|
|
2
|
+
import { DeriveSequenceElement } from './sequence.js';
|
|
3
|
+
export declare const createUnionParser: <Output, Sequence, Element = DeriveSequenceElement<Sequence>>(childParsers: Array<Parser<unknown, Sequence, Element>>) => Parser<Output, Sequence, Element>;
|
package/build/unionParser.js
CHANGED
|
@@ -2,30 +2,42 @@ import { allSettledStream } from './allSettledStream.js';
|
|
|
2
2
|
import { getParserName, setParserName } from './parser.js';
|
|
3
3
|
import { ParserParsingFailedError } from './parserError.js';
|
|
4
4
|
import { parserImplementationInvariant } from './parserImplementationInvariant.js';
|
|
5
|
+
const bigintReplacer = (_key, value) => {
|
|
6
|
+
if (typeof value === 'bigint') {
|
|
7
|
+
return `${value}n`;
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
};
|
|
5
11
|
export const createUnionParser = (childParsers) => {
|
|
6
12
|
parserImplementationInvariant(childParsers.length > 0, 'Union parser must have at least one child parser.');
|
|
7
13
|
const unionParser = async (parserContext) => {
|
|
8
14
|
let runningChildParserContexts = [];
|
|
9
|
-
const
|
|
15
|
+
const createChildParserTask = (childParser) => {
|
|
10
16
|
const childParserContext = parserContext.lookahead({
|
|
11
17
|
debugName: getParserName(childParser, 'anonymousUnionChild'),
|
|
12
18
|
});
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const context = {
|
|
20
|
+
childParser,
|
|
21
|
+
childParserContext,
|
|
22
|
+
};
|
|
23
|
+
runningChildParserContexts.push(context);
|
|
24
|
+
const getChildParserPromise = (async () => childParser(childParserContext));
|
|
25
|
+
const promise = getChildParserPromise();
|
|
15
26
|
return {
|
|
16
27
|
promise,
|
|
17
|
-
context
|
|
28
|
+
context,
|
|
18
29
|
};
|
|
19
|
-
}
|
|
30
|
+
};
|
|
31
|
+
const childParserResults = allSettledStream(childParsers.map(createChildParserTask));
|
|
20
32
|
const parserParsingFailedErrors = [];
|
|
21
33
|
const successfulParserOutputs = [];
|
|
22
|
-
const
|
|
34
|
+
const successfulTaskContexts = [];
|
|
23
35
|
let didUnlookahead = false;
|
|
24
36
|
for await (const childParserResult of childParserResults) {
|
|
25
37
|
runningChildParserContexts = runningChildParserContexts.filter(runningChildParserContext => runningChildParserContext !== childParserResult.context);
|
|
26
38
|
if (childParserResult.status === 'fulfilled') {
|
|
27
39
|
successfulParserOutputs.push(childParserResult.value);
|
|
28
|
-
|
|
40
|
+
successfulTaskContexts.push(childParserResult.context);
|
|
29
41
|
}
|
|
30
42
|
else {
|
|
31
43
|
const error = childParserResult.reason;
|
|
@@ -41,7 +53,7 @@ export const createUnionParser = (childParsers) => {
|
|
|
41
53
|
parserImplementationInvariant(!didUnlookahead, 'Union parser unlookaheaded multiple times.');
|
|
42
54
|
didUnlookahead = true;
|
|
43
55
|
const [runningChildParserContext] = runningChildParserContexts;
|
|
44
|
-
runningChildParserContext.unlookahead();
|
|
56
|
+
runningChildParserContext.childParserContext.unlookahead();
|
|
45
57
|
}
|
|
46
58
|
}
|
|
47
59
|
parserImplementationInvariant(successfulParserOutputs.length <= 1, [
|
|
@@ -49,13 +61,16 @@ export const createUnionParser = (childParsers) => {
|
|
|
49
61
|
'Successful parser outputs, indented, separated by newlines:',
|
|
50
62
|
'%s',
|
|
51
63
|
'End of successful parser outputs.',
|
|
52
|
-
|
|
64
|
+
'Successful parser names, indented, separated by newlines:',
|
|
65
|
+
'%s',
|
|
66
|
+
'End of successful parser names.',
|
|
67
|
+
], () => successfulParserOutputs.map(output => ' ' + JSON.stringify(output, bigintReplacer)).join('\n'), () => successfulTaskContexts.map(taskContext => ' ' + getParserName(taskContext.childParser, 'anonymousUnionChild')).join('\n'));
|
|
53
68
|
parserContext.invariantJoin(successfulParserOutputs.length === 1, parserParsingFailedErrors, 'No union child parser succeeded.');
|
|
54
|
-
const [successfulParserContext] =
|
|
69
|
+
const [successfulParserContext] = successfulTaskContexts;
|
|
55
70
|
if (!didUnlookahead) {
|
|
56
|
-
successfulParserContext.unlookahead();
|
|
71
|
+
successfulParserContext.childParserContext.unlookahead();
|
|
57
72
|
}
|
|
58
|
-
successfulParserContext.dispose();
|
|
73
|
+
successfulParserContext.childParserContext.dispose();
|
|
59
74
|
const [successfulParserOutput] = successfulParserOutputs;
|
|
60
75
|
return successfulParserOutput;
|
|
61
76
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { createUnionParser } from './unionParser.js';
|
|
3
|
+
import { runParser, setParserName } from './parser.js';
|
|
4
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
|
+
import { createArrayParser } from './arrayParser.js';
|
|
6
|
+
import { createExactElementParser } from './exactElementParser.js';
|
|
7
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
8
|
+
import { ParserError } from './parserError.js';
|
|
9
|
+
test('union of union of union', async (t) => {
|
|
10
|
+
const parser = createUnionParser([
|
|
11
|
+
createExactElementParser('a'),
|
|
12
|
+
createUnionParser([
|
|
13
|
+
createExactElementParser('b'),
|
|
14
|
+
createUnionParser([
|
|
15
|
+
createExactElementParser('c'),
|
|
16
|
+
createExactElementParser('d'),
|
|
17
|
+
]),
|
|
18
|
+
createExactElementParser('e'),
|
|
19
|
+
]),
|
|
20
|
+
createExactElementParser('f'),
|
|
21
|
+
createUnionParser([
|
|
22
|
+
createExactElementParser('g'),
|
|
23
|
+
createExactElementParser('h'),
|
|
24
|
+
]),
|
|
25
|
+
]);
|
|
26
|
+
for (const character of 'abcdefgh') {
|
|
27
|
+
t.deepEqual(await runParser(parser, character, stringParserInputCompanion), character);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
test('sync and async child parsers', async (t) => {
|
|
31
|
+
const parser = createArrayParser(createUnionParser([
|
|
32
|
+
async (parserContext) => {
|
|
33
|
+
parserContext.invariant(parserContext.position % 2 === 0, 'Expected an even position.');
|
|
34
|
+
return parserContext.read(0);
|
|
35
|
+
},
|
|
36
|
+
parserContext => {
|
|
37
|
+
parserContext.invariant(parserContext.position % 2 === 1, 'Expected an odd position.');
|
|
38
|
+
parserContext.skip(1);
|
|
39
|
+
return String.fromCodePoint('A'.codePointAt(0) + parserContext.position - 1);
|
|
40
|
+
},
|
|
41
|
+
]));
|
|
42
|
+
const result = await runParser(parser, 'a?c?', stringParserInputCompanion, {
|
|
43
|
+
errorJoinMode: 'all',
|
|
44
|
+
});
|
|
45
|
+
t.deepEqual(result, 'aBcD'.split(''));
|
|
46
|
+
});
|
|
47
|
+
test('multiple parsers succeeded error', async (t) => {
|
|
48
|
+
const parser = createUnionParser([
|
|
49
|
+
setParserName(createExactSequenceParser('foo'), 'foo1'),
|
|
50
|
+
setParserName(createExactSequenceParser('foo'), 'foo2'),
|
|
51
|
+
]);
|
|
52
|
+
const error = await t.throwsAsync(runParser(parser, 'foo', stringParserInputCompanion, {
|
|
53
|
+
errorJoinMode: 'all',
|
|
54
|
+
}), {
|
|
55
|
+
instanceOf: ParserError,
|
|
56
|
+
});
|
|
57
|
+
t.true(error.message.includes('foo'));
|
|
58
|
+
t.true(error.message.includes('foo1'));
|
|
59
|
+
t.true(error.message.includes('foo2'));
|
|
60
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DeriveSequenceElement } from "./sequence.js";
|
|
2
|
+
import { UnparserContext, WriteEarlier, WriteLater } from "./unparserContext.js";
|
|
3
|
+
import { UnparserOutputCompanion } from "./unparserOutputCompanion.js";
|
|
4
|
+
type UnparserIterableValue<Sequence, Element> = Sequence | Element | WriteLater<Sequence, Element> | WriteEarlier<Sequence, Element>;
|
|
5
|
+
export type UnparserResult<Sequence, Element> = AsyncIterable<UnparserIterableValue<Sequence, Element>>;
|
|
6
|
+
export type Unparser<Input, Sequence, Element = DeriveSequenceElement<Sequence>> = (input: Input, unparserContext: UnparserContext<Sequence, Element>) => UnparserResult<Sequence, Element>;
|
|
7
|
+
export declare function runUnparser<Input, Sequence, Element = DeriveSequenceElement<Sequence>>(unparser: Unparser<Input, Sequence, Element>, input: Input, unparserOutputCompanion: UnparserOutputCompanion<Sequence, Element>): AsyncIterable<Sequence>;
|
|
8
|
+
export {};
|