@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.
Files changed (311) hide show
  1. package/.github/copilot-instructions.md +149 -0
  2. package/.github/workflows/copilot-setup-steps.yml +18 -0
  3. package/.github/workflows/main.yml +29 -8
  4. package/.yarn/releases/yarn-4.9.4.cjs +942 -0
  5. package/.yarnrc.yml +1 -1
  6. package/build/allSettledStream.js +1 -1
  7. package/build/allSettledStream.test.js +2 -2
  8. package/build/androidPackageParser.d.ts +1 -1
  9. package/build/androidPackageParser.js +5 -3
  10. package/build/androidPackageParser.test.js +7 -7
  11. package/build/androidPackageUnparser.d.ts +2 -2
  12. package/build/androidPackageUnparser.js +18 -14
  13. package/build/androidPackageUnparser.test.js +7 -7
  14. package/build/arbitrarilySlicedAsyncInterator.js +2 -1
  15. package/build/arbitraryDalvikBytecode.d.ts +4 -0
  16. package/build/arbitraryDalvikBytecode.js +640 -0
  17. package/build/arbitraryDalvikExecutable.d.ts +3 -0
  18. package/build/arbitraryDalvikExecutable.js +282 -0
  19. package/build/arbitraryDosDateTime.js +1 -0
  20. package/build/arbitraryZipStream.js +1 -1
  21. package/build/arrayParser.js +2 -2
  22. package/build/arrayUnparser.d.ts +1 -1
  23. package/build/backsmali.d.ts +3 -1
  24. package/build/backsmali.js +31 -3
  25. package/build/bash.d.ts +84 -0
  26. package/build/bash.js +1 -0
  27. package/build/bashParser.d.ts +6 -0
  28. package/build/bashParser.js +294 -0
  29. package/build/bashParser.test.d.ts +1 -0
  30. package/build/bashParser.test.js +181 -0
  31. package/build/customInvariant.d.ts +2 -1
  32. package/build/customInvariant.js +4 -6
  33. package/build/dalvikBytecodeParser/formatParsers.d.ts +76 -2
  34. package/build/dalvikBytecodeParser/formatParsers.js +146 -11
  35. package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
  36. package/build/dalvikBytecodeParser/formatSizes.js +34 -0
  37. package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
  38. package/build/dalvikBytecodeParser/operationFormats.js +225 -0
  39. package/build/dalvikBytecodeParser.d.ts +1105 -5
  40. package/build/dalvikBytecodeParser.js +658 -205
  41. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
  42. package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
  43. package/build/dalvikBytecodeUnparser.d.ts +3 -0
  44. package/build/dalvikBytecodeUnparser.js +642 -0
  45. package/build/dalvikBytecodeUnparser.test.d.ts +1 -0
  46. package/build/dalvikBytecodeUnparser.test.js +25 -0
  47. package/build/dalvikExecutable.d.ts +65 -8
  48. package/build/dalvikExecutable.js +36 -0
  49. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +1 -1
  50. package/build/dalvikExecutableParser/stringSyntaxParser.js +17 -17
  51. package/build/dalvikExecutableParser/typeParsers.d.ts +2 -1
  52. package/build/dalvikExecutableParser/typeParsers.js +16 -11
  53. package/build/dalvikExecutableParser/typedNumbers.d.ts +85 -69
  54. package/build/dalvikExecutableParser/typedNumbers.js +0 -1
  55. package/build/dalvikExecutableParser.d.ts +2 -2
  56. package/build/dalvikExecutableParser.js +655 -337
  57. package/build/dalvikExecutableParser.test.js +24 -22
  58. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +223 -246
  59. package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
  60. package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
  61. package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
  62. package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
  63. package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
  64. package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
  65. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
  66. package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
  67. package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
  68. package/build/dalvikExecutableUnparser/utils.js +108 -0
  69. package/build/dalvikExecutableUnparser.d.ts +4 -0
  70. package/build/dalvikExecutableUnparser.js +406 -0
  71. package/build/dalvikExecutableUnparser.test.d.ts +1 -0
  72. package/build/dalvikExecutableUnparser.test.js +31 -0
  73. package/build/debugLogInputParser.js +1 -1
  74. package/build/disjunctionParser.d.ts +2 -2
  75. package/build/disjunctionParser.js +2 -2
  76. package/build/elementTerminatedArrayParser.d.ts +2 -2
  77. package/build/elementTerminatedArrayParser.js +1 -1
  78. package/build/elementTerminatedArrayParser.test.js +5 -5
  79. package/build/elementTerminatedSequenceArrayParser.d.ts +2 -2
  80. package/build/elementTerminatedSequenceArrayParser.js +1 -1
  81. package/build/elementTerminatedSequenceArrayParser.test.js +2 -2
  82. package/build/elementTerminatedSequenceParser.d.ts +2 -2
  83. package/build/elementTerminatedSequenceParser.js +1 -1
  84. package/build/elementTerminatedSequenceParser.test.js +2 -2
  85. package/build/endOfInputParser.d.ts +1 -1
  86. package/build/exactElementSwitchParser.d.ts +3 -0
  87. package/build/exactElementSwitchParser.js +22 -0
  88. package/build/fetchCid.js +2 -6
  89. package/build/fetchCid.test.d.ts +1 -0
  90. package/build/fetchCid.test.js +16 -0
  91. package/build/fixedLengthSequenceParser.test.js +2 -2
  92. package/build/hasExecutable.js +2 -2
  93. package/build/highResolutionTimer.js +1 -1
  94. package/build/index.d.ts +24 -2
  95. package/build/index.js +22 -1
  96. package/build/inputReader.d.ts +1 -1
  97. package/build/inputReader.test.js +33 -45
  98. package/build/javaKeyStoreParser.test.js +6 -6
  99. package/build/jsonParser.js +8 -8
  100. package/build/lazyMessageError.d.ts +48 -0
  101. package/build/lazyMessageError.js +53 -0
  102. package/build/lazyMessageError.test.d.ts +1 -0
  103. package/build/lazyMessageError.test.js +15 -0
  104. package/build/leb128Parser.d.ts +1 -1
  105. package/build/leb128Parser.js +10 -10
  106. package/build/leb128Parser.test.js +7 -7
  107. package/build/negativeLookaheadParser.js +2 -2
  108. package/build/negativeLookaheadParser.test.js +4 -4
  109. package/build/noStackCaptureOverheadError.d.ts +4 -0
  110. package/build/noStackCaptureOverheadError.js +9 -0
  111. package/build/noStackCaptureOverheadError.test.d.ts +1 -0
  112. package/build/noStackCaptureOverheadError.test.js +15 -0
  113. package/build/nonEmptyArrayParser.js +2 -2
  114. package/build/nonEmptyArrayParser.test.js +2 -1
  115. package/build/optionalParser.js +2 -2
  116. package/build/parser.d.ts +2 -1
  117. package/build/parser.js +23 -8
  118. package/build/parser.test.js +78 -29
  119. package/build/parserConsumedSequenceParser.d.ts +1 -1
  120. package/build/parserConsumedSequenceParser.js +2 -2
  121. package/build/parserContext.d.ts +8 -6
  122. package/build/parserContext.js +60 -33
  123. package/build/parserContext.test.js +7 -3
  124. package/build/parserError.d.ts +603 -44
  125. package/build/parserError.js +98 -53
  126. package/build/parserImplementationInvariant.d.ts +1 -1
  127. package/build/parserImplementationInvariant.js +2 -2
  128. package/build/parserInputCompanion.js +2 -2
  129. package/build/promiseCompose.js +1 -2
  130. package/build/regexpParser.d.ts +2 -0
  131. package/build/regexpParser.js +71 -0
  132. package/build/regexpParser.test.d.ts +1 -0
  133. package/build/regexpParser.test.js +83 -0
  134. package/build/regularExpression.d.ts +63 -0
  135. package/build/regularExpression.js +1 -0
  136. package/build/regularExpressionParser.d.ts +3 -0
  137. package/build/regularExpressionParser.js +580 -0
  138. package/build/regularExpressionParser.test.d.ts +1 -0
  139. package/build/regularExpressionParser.test.js +89 -0
  140. package/build/separatedArrayParser.js +2 -2
  141. package/build/separatedNonEmptyArrayParser.d.ts +2 -0
  142. package/build/separatedNonEmptyArrayParser.js +40 -0
  143. package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
  144. package/build/separatedNonEmptyArrayParser.test.js +66 -0
  145. package/build/sequenceBuffer.js +1 -1
  146. package/build/sequenceTerminatedSequenceParser.d.ts +2 -2
  147. package/build/sequenceTerminatedSequenceParser.js +3 -3
  148. package/build/sequenceTerminatedSequenceParser.test.js +1 -1
  149. package/build/sequenceUnparser.d.ts +1 -1
  150. package/build/skipToParser.d.ts +1 -1
  151. package/build/skipToParser.js +2 -2
  152. package/build/sliceBoundedParser.test.js +4 -9
  153. package/build/smali.d.ts +1 -1
  154. package/build/smali.js +6 -2
  155. package/build/smaliParser.d.ts +62 -6
  156. package/build/smaliParser.js +1721 -296
  157. package/build/smaliParser.test.js +338 -43
  158. package/build/stringFromAsyncIterable.d.ts +1 -0
  159. package/build/stringFromAsyncIterable.js +7 -0
  160. package/build/terminatedArrayParser.js +4 -4
  161. package/build/terminatedArrayParser.test.js +7 -7
  162. package/build/toAsyncIterator.js +4 -4
  163. package/build/unionParser.d.ts +1 -1
  164. package/build/unionParser.js +2 -2
  165. package/build/unionParser.test.js +3 -3
  166. package/build/unparser.d.ts +3 -3
  167. package/build/unparser.js +6 -4
  168. package/build/unparser.test.js +7 -19
  169. package/build/unparserContext.d.ts +2 -2
  170. package/build/unparserContext.js +2 -3
  171. package/build/unparserError.d.ts +2 -1
  172. package/build/unparserError.js +2 -1
  173. package/build/unparserImplementationInvariant.d.ts +1 -1
  174. package/build/unparserOutputCompanion.d.ts +1 -1
  175. package/build/unparserOutputCompanion.js +1 -1
  176. package/build/zipParser.js +1 -1
  177. package/build/zipUnparser.d.ts +3 -3
  178. package/build/zipUnparser.js +9 -19
  179. package/build/zipUnparser.test.js +1 -1
  180. package/package.json +20 -26
  181. package/src/allSettledStream.test.ts +2 -2
  182. package/src/allSettledStream.ts +3 -3
  183. package/src/androidPackageParser.test.ts +17 -19
  184. package/src/androidPackageParser.ts +129 -171
  185. package/src/androidPackageUnparser.test.ts +19 -21
  186. package/src/androidPackageUnparser.ts +23 -17
  187. package/src/arbitrarilySlicedAsyncInterable.ts +1 -1
  188. package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
  189. package/src/arbitraryDalvikBytecode.ts +992 -0
  190. package/src/arbitraryDalvikExecutable.ts +434 -0
  191. package/src/arbitraryDosDateTime.ts +1 -0
  192. package/src/arbitraryZipStream.ts +1 -1
  193. package/src/arrayParser.ts +2 -2
  194. package/src/arrayUnparser.ts +2 -2
  195. package/src/backsmali.ts +48 -4
  196. package/src/bash.ts +120 -0
  197. package/src/bashParser.test.ts +332 -0
  198. package/src/bashParser.ts +461 -0
  199. package/src/bsonParser.test.ts +12 -14
  200. package/src/customInvariant.ts +8 -12
  201. package/src/dalvikBytecodeParser/formatParsers.ts +376 -17
  202. package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
  203. package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
  204. package/src/dalvikBytecodeParser.ts +1042 -243
  205. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
  206. package/src/dalvikBytecodeUnparser.test.ts +44 -0
  207. package/src/dalvikBytecodeUnparser.ts +758 -0
  208. package/src/dalvikExecutable.ts +110 -48
  209. package/src/dalvikExecutableParser/stringSyntaxParser.ts +33 -33
  210. package/src/dalvikExecutableParser/typeParsers.ts +23 -14
  211. package/src/dalvikExecutableParser/typedNumbers.ts +19 -19
  212. package/src/dalvikExecutableParser.test.ts +60 -60
  213. package/src/dalvikExecutableParser.test.ts.md +6 -6
  214. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  215. package/src/dalvikExecutableParser.ts +911 -434
  216. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +256 -239
  217. package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
  218. package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
  219. package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
  220. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
  221. package/src/dalvikExecutableUnparser/utils.ts +149 -0
  222. package/src/dalvikExecutableUnparser.test.ts +57 -0
  223. package/src/dalvikExecutableUnparser.ts +581 -0
  224. package/src/debugLogInputParser.ts +1 -1
  225. package/src/disjunctionParser.ts +5 -5
  226. package/src/elementTerminatedArrayParser.test.ts +8 -8
  227. package/src/elementTerminatedArrayParser.ts +2 -2
  228. package/src/elementTerminatedSequenceArrayParser.test.ts +4 -6
  229. package/src/elementTerminatedSequenceArrayParser.ts +2 -2
  230. package/src/elementTerminatedSequenceParser.test.ts +4 -6
  231. package/src/elementTerminatedSequenceParser.ts +2 -2
  232. package/src/endOfInputParser.ts +1 -1
  233. package/src/exactElementSwitchParser.ts +41 -0
  234. package/src/fetchCid.test.ts +20 -0
  235. package/src/fetchCid.ts +3 -7
  236. package/src/fixedLengthSequenceParser.test.ts +10 -12
  237. package/src/hasExecutable.ts +2 -2
  238. package/src/highResolutionTimer.ts +1 -1
  239. package/src/index.ts +113 -2
  240. package/src/inputReader.test.ts +39 -52
  241. package/src/inputReader.ts +2 -4
  242. package/src/inputReaderState.ts +1 -1
  243. package/src/inspect.ts +1 -1
  244. package/src/javaKeyStoreParser.test.ts +12 -14
  245. package/src/javaKeyStoreParser.ts +2 -6
  246. package/src/jsonParser.test.ts +2 -4
  247. package/src/jsonParser.ts +34 -38
  248. package/src/lazyMessageError.test.ts +21 -0
  249. package/src/lazyMessageError.ts +88 -0
  250. package/src/leb128Parser.test.ts +25 -23
  251. package/src/leb128Parser.ts +19 -19
  252. package/src/negativeLookaheadParser.test.ts +7 -11
  253. package/src/negativeLookaheadParser.ts +2 -2
  254. package/src/noStackCaptureOverheadError.test.ts +17 -0
  255. package/src/noStackCaptureOverheadError.ts +12 -0
  256. package/src/nonEmptyArrayParser.test.ts +3 -2
  257. package/src/nonEmptyArrayParser.ts +2 -2
  258. package/src/optionalParser.ts +2 -2
  259. package/src/parser.test.ts +96 -43
  260. package/src/parser.test.ts.md +13 -6
  261. package/src/parser.test.ts.snap +0 -0
  262. package/src/parser.ts +35 -12
  263. package/src/parserAccessorParser.ts +1 -1
  264. package/src/parserConsumedSequenceParser.ts +3 -3
  265. package/src/parserContext.test.ts +7 -3
  266. package/src/parserContext.ts +82 -48
  267. package/src/parserError.ts +143 -63
  268. package/src/parserImplementationInvariant.ts +3 -3
  269. package/src/parserInputCompanion.ts +2 -2
  270. package/src/promiseCompose.ts +2 -2
  271. package/src/regexpParser.test.ts +186 -0
  272. package/src/regexpParser.ts +94 -0
  273. package/src/regularExpression.ts +24 -0
  274. package/src/regularExpressionParser.test.ts +102 -0
  275. package/src/regularExpressionParser.ts +921 -0
  276. package/src/separatedArrayParser.ts +3 -3
  277. package/src/separatedNonEmptyArrayParser.test.ts +117 -0
  278. package/src/separatedNonEmptyArrayParser.ts +61 -0
  279. package/src/sequenceBuffer.test.ts +9 -9
  280. package/src/sequenceBuffer.ts +4 -4
  281. package/src/sequenceTerminatedSequenceParser.test.ts +3 -5
  282. package/src/sequenceTerminatedSequenceParser.ts +4 -4
  283. package/src/sequenceUnparser.ts +2 -2
  284. package/src/skipToParser.ts +2 -2
  285. package/src/sliceBoundedParser.test.ts +4 -12
  286. package/src/sliceBoundedParser.ts +2 -2
  287. package/src/smali.ts +8 -3
  288. package/src/smaliParser.test.ts +377 -66
  289. package/src/smaliParser.test.ts.md +1635 -48
  290. package/src/smaliParser.test.ts.snap +0 -0
  291. package/src/smaliParser.ts +2751 -569
  292. package/src/stringFromAsyncIterable.ts +9 -0
  293. package/src/terminatedArrayParser.test.ts +11 -11
  294. package/src/terminatedArrayParser.ts +5 -7
  295. package/src/toAsyncIterator.ts +8 -8
  296. package/src/uint8Array.ts +2 -3
  297. package/src/unionParser.test.ts +22 -23
  298. package/src/unionParser.ts +6 -8
  299. package/src/unparser.test.ts +18 -34
  300. package/src/unparser.ts +13 -9
  301. package/src/unparserContext.ts +9 -13
  302. package/src/unparserError.ts +2 -1
  303. package/src/unparserImplementationInvariant.ts +1 -1
  304. package/src/unparserOutputCompanion.ts +1 -1
  305. package/src/zip.ts +2 -6
  306. package/src/zipParser.ts +10 -18
  307. package/src/zipUnparser.test.ts +1 -1
  308. package/src/zipUnparser.ts +52 -64
  309. package/tsconfig.json +7 -1
  310. package/xo.config.ts +15 -0
  311. package/.yarn/releases/yarn-4.5.3.cjs +0 -934
@@ -1,5 +1,5 @@
1
1
  import { getParserName, type Parser, setParserName } from './parser.js';
2
- import { ParserParsingFailedError } from './parserError.js';
2
+ import { isParserParsingFailedError } from './parserError.js';
3
3
  import { promiseCompose } from './promiseCompose.js';
4
4
  import { createTupleParser } from './tupleParser.js';
5
5
 
@@ -34,7 +34,7 @@ export const createSeparatedArrayParser = <ElementOutput, Sequence>(
34
34
  elements.push(element);
35
35
  elementParserContext.unlookahead();
36
36
  } catch (error) {
37
- if (error instanceof ParserParsingFailedError) {
37
+ if (isParserParsingFailedError(error)) {
38
38
  break;
39
39
  }
40
40
 
@@ -43,7 +43,7 @@ export const createSeparatedArrayParser = <ElementOutput, Sequence>(
43
43
  elementParserContext.dispose();
44
44
  }
45
45
 
46
- parser = separatorThenElementParser
46
+ parser = separatorThenElementParser;
47
47
  }
48
48
 
49
49
  return elements;
@@ -0,0 +1,117 @@
1
+ import test from 'ava';
2
+ import { testProp, fc } from '@fast-check/ava';
3
+ import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
4
+ import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
5
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
6
+ import { createExactSequenceParser } from './exactSequenceParser.js';
7
+ import { stringFromAsyncIterable } from './stringFromAsyncIterable.js';
8
+
9
+ test('empty input throws error', async t => {
10
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
11
+ createExactSequenceParser('element'),
12
+ createExactSequenceParser(','),
13
+ );
14
+
15
+ await t.throwsAsync(async () => runParser(parser, '', stringParserInputCompanion), {
16
+ any: true,
17
+ message: /Expected .* to match at least once/,
18
+ });
19
+ });
20
+
21
+ test('single element without separator matches', async t => {
22
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
23
+ createExactSequenceParser('element'),
24
+ createExactSequenceParser(','),
25
+ );
26
+
27
+ const result = await runParser(parser, 'element', stringParserInputCompanion);
28
+ t.deepEqual(result, [ 'element' ]);
29
+ });
30
+
31
+ test('two elements with separator matches', async t => {
32
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
33
+ createExactSequenceParser('element'),
34
+ createExactSequenceParser(','),
35
+ );
36
+
37
+ const result = await runParser(parser, 'element,element', stringParserInputCompanion);
38
+ t.deepEqual(result, [ 'element', 'element' ]);
39
+ });
40
+
41
+ test('multiple elements with separator matches', async t => {
42
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
43
+ createExactSequenceParser('a'),
44
+ createExactSequenceParser(','),
45
+ );
46
+
47
+ const result = await runParser(parser, 'a,a,a,a', stringParserInputCompanion);
48
+ t.deepEqual(result, [ 'a', 'a', 'a', 'a' ]);
49
+ });
50
+
51
+ test('does not consume trailing separator', async t => {
52
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
53
+ createExactSequenceParser('element'),
54
+ createExactSequenceParser(','),
55
+ );
56
+
57
+ const { output, remainingInput } = await runParserWithRemainingInput(parser, 'element,element,', stringParserInputCompanion);
58
+ t.deepEqual(output, [ 'element', 'element' ]);
59
+ t.is(await stringFromAsyncIterable(remainingInput!), ',');
60
+ });
61
+
62
+ test('does not loop forever with a child parser that does not consume anything', async t => {
63
+ const parser: Parser<undefined[], string> = createSeparatedNonEmptyArrayParser(
64
+ async () => undefined,
65
+ () => undefined,
66
+ );
67
+
68
+ await t.throwsAsync(async () => runParser(parser, 'foo', stringParserInputCompanion), {
69
+ any: true,
70
+ message: /Expected .* to match at least once/,
71
+ });
72
+ });
73
+
74
+ test('partial match throws error', async t => {
75
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
76
+ createExactSequenceParser('element'),
77
+ createExactSequenceParser(','),
78
+ );
79
+
80
+ await t.throwsAsync(async () => runParser(parser, 'elem', stringParserInputCompanion), {
81
+ any: true,
82
+ message: /Expected .* to match at least once/,
83
+ });
84
+ });
85
+
86
+ testProp(
87
+ 'separatedNonEmptyArray with at least one element',
88
+ [
89
+ fc.array(fc.constant('element'), { minLength: 1 }),
90
+ ],
91
+ async (t, elements) => {
92
+ const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
93
+ createExactSequenceParser('element'),
94
+ createExactSequenceParser('separator'),
95
+ );
96
+
97
+ const actual = await runParser(separatedNonEmptyArrayParser, elements.join('separator'), stringParserInputCompanion);
98
+ const expected = elements;
99
+
100
+ t.deepEqual(actual, expected);
101
+ },
102
+ {
103
+ verbose: true,
104
+ },
105
+ );
106
+
107
+ test('separatedNonEmptyArray throws on empty array', async t => {
108
+ const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
109
+ createExactSequenceParser('element'),
110
+ createExactSequenceParser('separator'),
111
+ );
112
+
113
+ await t.throwsAsync(async () => runParser(separatedNonEmptyArrayParser, '', stringParserInputCompanion), {
114
+ any: true,
115
+ message: /Expected .* to match at least once/,
116
+ });
117
+ });
@@ -0,0 +1,61 @@
1
+ import { getParserName, type Parser, setParserName } from './parser.js';
2
+ import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
3
+ import { promiseCompose } from './promiseCompose.js';
4
+ import { createTupleParser } from './tupleParser.js';
5
+
6
+ export const createSeparatedNonEmptyArrayParser = <ElementOutput, Sequence>(
7
+ elementParser: Parser<ElementOutput, Sequence>,
8
+ separatorParser: Parser<unknown, Sequence>,
9
+ ): Parser<ElementOutput[], Sequence> => {
10
+ const separatorThenElementParser: Parser<ElementOutput, Sequence> = promiseCompose(
11
+ createTupleParser([
12
+ separatorParser,
13
+ elementParser,
14
+ ]),
15
+ ([ , element ]) => element,
16
+ );
17
+
18
+ const separatedNonEmptyArrayParser: Parser<ElementOutput[], Sequence> = async parserContext => {
19
+ let parser = elementParser;
20
+
21
+ const elements: ElementOutput[] = [];
22
+
23
+ while (true) {
24
+ const elementParserContext = parserContext.lookahead();
25
+ const initialPosition = elementParserContext.position;
26
+
27
+ try {
28
+ const element = await parser(elementParserContext);
29
+
30
+ if (elementParserContext.position === initialPosition) {
31
+ break;
32
+ }
33
+
34
+ elements.push(element);
35
+ elementParserContext.unlookahead();
36
+ } catch (error) {
37
+ if (isParserParsingFailedError(error)) {
38
+ break;
39
+ }
40
+
41
+ throw error;
42
+ } finally {
43
+ elementParserContext.dispose();
44
+ }
45
+
46
+ parser = separatorThenElementParser;
47
+ }
48
+
49
+ parserContext.invariant(
50
+ elements.length > 0,
51
+ 'Expected elementParser (%s) to match at least once',
52
+ getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild'),
53
+ );
54
+
55
+ return elements;
56
+ };
57
+
58
+ setParserName(separatedNonEmptyArrayParser, getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild') + '+');
59
+
60
+ return separatedNonEmptyArrayParser;
61
+ };
@@ -33,7 +33,7 @@ test('sequenceBuffer', t => {
33
33
 
34
34
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
35
35
  consumedBufferedSequences: [],
36
- unconsumedBufferedSequences: ['abc'],
36
+ unconsumedBufferedSequences: [ 'abc' ],
37
37
  });
38
38
 
39
39
  sequenceBuffer.push('def');
@@ -50,7 +50,7 @@ test('sequenceBuffer', t => {
50
50
 
51
51
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
52
52
  consumedBufferedSequences: [],
53
- unconsumedBufferedSequences: ['abc', 'def'],
53
+ unconsumedBufferedSequences: [ 'abc', 'def' ],
54
54
  });
55
55
 
56
56
  sequenceBuffer.push('');
@@ -62,7 +62,7 @@ test('sequenceBuffer', t => {
62
62
 
63
63
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
64
64
  consumedBufferedSequences: [],
65
- unconsumedBufferedSequences: ['abc', 'def', ''],
65
+ unconsumedBufferedSequences: [ 'abc', 'def', '' ],
66
66
  });
67
67
 
68
68
  sequenceBuffer.skip(1);
@@ -73,8 +73,8 @@ test('sequenceBuffer', t => {
73
73
  t.is(sequenceBuffer.peek(5), undefined);
74
74
 
75
75
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
76
- consumedBufferedSequences: ['a'],
77
- unconsumedBufferedSequences: ['bc', 'def', ''],
76
+ consumedBufferedSequences: [ 'a' ],
77
+ unconsumedBufferedSequences: [ 'bc', 'def', '' ],
78
78
  });
79
79
 
80
80
  sequenceBuffer.skip(3);
@@ -84,8 +84,8 @@ test('sequenceBuffer', t => {
84
84
  t.is(sequenceBuffer.peek(2), undefined);
85
85
 
86
86
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
87
- consumedBufferedSequences: ['d'],
88
- unconsumedBufferedSequences: ['ef', ''],
87
+ consumedBufferedSequences: [ 'd' ],
88
+ unconsumedBufferedSequences: [ 'ef', '' ],
89
89
  });
90
90
 
91
91
  sequenceBuffer.push('gh');
@@ -101,8 +101,8 @@ test('sequenceBuffer', t => {
101
101
  t.is(sequenceBuffer.peekSequence(1, 5), undefined, 'fgh?');
102
102
 
103
103
  t.deepEqual(sequenceBuffer.toSequenceBufferState(), {
104
- consumedBufferedSequences: ['d'],
105
- unconsumedBufferedSequences: ['ef', '', 'gh'],
104
+ consumedBufferedSequences: [ 'd' ],
105
+ unconsumedBufferedSequences: [ 'ef', '', 'gh' ],
106
106
  });
107
107
  });
108
108
 
@@ -88,7 +88,7 @@ export class SequenceBufferImplementation<Sequence, Element> implements Sequence
88
88
  sequence,
89
89
  Math.max(0, startIndex),
90
90
  Math.min(sequenceLength, endIndex),
91
- )
91
+ );
92
92
  sequences.push(subsequence);
93
93
  }
94
94
 
@@ -120,7 +120,7 @@ export class SequenceBufferImplementation<Sequence, Element> implements Sequence
120
120
  if (this._indexInFirstSequence === 0) {
121
121
  return {
122
122
  consumedBufferedSequences: [],
123
- unconsumedBufferedSequences: this._sequences.slice(),
123
+ unconsumedBufferedSequences: [ ...this._sequences ],
124
124
  };
125
125
  }
126
126
 
@@ -133,11 +133,11 @@ export class SequenceBufferImplementation<Sequence, Element> implements Sequence
133
133
  const unconsumedFirstSequenceLength = this._parserInputCompanion.length(unconsumedFirstSequence);
134
134
 
135
135
  return {
136
- consumedBufferedSequences: [consumedFirstSequence],
136
+ consumedBufferedSequences: [ consumedFirstSequence ],
137
137
  unconsumedBufferedSequences: (
138
138
  unconsumedFirstSequenceLength === 0
139
139
  ? this._sequences.slice(1)
140
- : [unconsumedFirstSequence, ...this._sequences.slice(1)]
140
+ : [ unconsumedFirstSequence, ...this._sequences.slice(1) ]
141
141
  ),
142
142
  };
143
143
  }
@@ -1,6 +1,6 @@
1
1
  import * as fc from 'fast-check';
2
2
  import { testProp } from '@fast-check/ava';
3
- import { Parser, runParser } from './parser.js';
3
+ import { type Parser, runParser } from './parser.js';
4
4
  import { stringParserInputCompanion } from './parserInputCompanion.js';
5
5
  import { createSequenceTerminatedSequenceParser } from './sequenceTerminatedSequenceParser.js';
6
6
 
@@ -21,12 +21,10 @@ testProp.serial(
21
21
  string,
22
22
  terminator: string.slice(-terminatorLength),
23
23
  }))
24
- .filter(({ string, terminator }) => string.split(terminator).length === 2)
24
+ .filter(({ string, terminator }) => string.split(terminator).length === 2),
25
25
  ],
26
26
  async (t, { string, terminator }) => {
27
- const sequenceTerminatedSequenceParser = createSequenceTerminatedSequenceParser<string>(
28
- terminator,
29
- );
27
+ const sequenceTerminatedSequenceParser = createSequenceTerminatedSequenceParser<string>(terminator);
30
28
 
31
29
  const createTestWrapperParser = (innerParser: typeof sequenceTerminatedSequenceParser): Parser<{
32
30
  string: string;
@@ -1,6 +1,6 @@
1
- import { inspect } from "./inspect.js";
2
- import { Parser, setParserName } from "./parser.js";
3
- import { DeriveSequenceElement } from "./sequence.js";
1
+ import { inspect } from './inspect.js';
2
+ import { type Parser, setParserName } from './parser.js';
3
+ import { type DeriveSequenceElement } from './sequence.js';
4
4
 
5
5
  function clamp(x: number, min: number, max: number) {
6
6
  return Math.max(min, Math.min(x, max));
@@ -41,7 +41,7 @@ export const createSequenceTerminatedSequenceParser = <Sequence, Element = Deriv
41
41
  const terminatorIndex = parserContext.indexOfSubsequence(sequence, terminatorSequence);
42
42
 
43
43
  if (terminatorIndex === -1) {
44
- window = window * 2;
44
+ window *= 2;
45
45
 
46
46
  continue;
47
47
  }
@@ -1,4 +1,4 @@
1
- import { Unparser } from "./unparser.js";
1
+ import { type Unparser } from './unparser.js';
2
2
 
3
3
  export const createSequenceUnparser = <Sequence>(): Unparser<Sequence, Sequence> => {
4
4
  const sequenceUnparser: Unparser<Sequence, Sequence> = async function * (input) {
@@ -6,4 +6,4 @@ export const createSequenceUnparser = <Sequence>(): Unparser<Sequence, Sequence>
6
6
  };
7
7
 
8
8
  return sequenceUnparser;
9
- }
9
+ };
@@ -1,8 +1,8 @@
1
- import { Parser, setParserName } from "./parser.js";
1
+ import { type Parser, setParserName } from './parser.js';
2
2
  import { parserImplementationInvariant } from './parserImplementationInvariant.js';
3
3
 
4
4
  export const createSkipToParser = (offset: number): Parser<void, Uint8Array> => {
5
- const skipToParser: Parser<void, Uint8Array> = (parserContext) => {
5
+ const skipToParser: Parser<void, Uint8Array> = parserContext => {
6
6
  const length = offset - parserContext.position;
7
7
 
8
8
  parserImplementationInvariant(length >= 0, 'Skip length must be positive, got %s (position: %s)', length, parserContext.position);
@@ -6,16 +6,7 @@ import { createSliceBoundedParser } from './sliceBoundedParser.js';
6
6
  import { runParser, runParserWithRemainingInput } from './parser.js';
7
7
  import { stringParserInputCompanion } from './parserInputCompanion.js';
8
8
  import { createExactElementParser } from './exactElementParser.js';
9
-
10
- async function stringFromAsyncIterable(asyncIterable: AsyncIterable<string>) {
11
- let string = '';
12
-
13
- for await (const chunk of asyncIterable) {
14
- string += chunk;
15
- }
16
-
17
- return string;
18
- }
9
+ import { stringFromAsyncIterable } from './stringFromAsyncIterable.js';
19
10
 
20
11
  const anythingParser = createArrayParser(createElementParser<string>());
21
12
 
@@ -45,7 +36,8 @@ test('sliceBoundedParser mustConsumeAll: true fail to cosume all', async t => {
45
36
  createElementParser(),
46
37
  ]);
47
38
 
48
- await t.throwsAsync(() => runParser(parser, 'abcd', stringParserInputCompanion), {
39
+ await t.throwsAsync(async () => runParser(parser, 'abcd', stringParserInputCompanion), {
40
+ any: true,
49
41
  message: /child parser must consume all input in the slice/,
50
42
  });
51
43
  });
@@ -66,5 +58,5 @@ test('sliceBoundedParser mustConsumeAll: false', async t => {
66
58
  ],
67
59
  'c',
68
60
  ]);
69
- t.deepEqual(await stringFromAsyncIterable(remainingInput!), 'd');
61
+ t.is(await stringFromAsyncIterable(remainingInput!), 'd');
70
62
  });
@@ -3,7 +3,7 @@ import { getParserName, type Parser, setParserName } from './parser.js';
3
3
  export const createSliceBoundedParser = <Output, Sequence>(
4
4
  childParser: Parser<Output, Sequence>,
5
5
  sliceEnd: number,
6
- mustConsumeAll: boolean = true,
6
+ mustConsumeAll = true,
7
7
  ): Parser<Output, Sequence> => {
8
8
  const sliceBoundedParser: typeof childParser = async parserContext => {
9
9
  const absoluteSliceEnd = parserContext.position + sliceEnd;
@@ -18,7 +18,7 @@ export const createSliceBoundedParser = <Output, Sequence>(
18
18
  childParserContext.invariant(
19
19
  (
20
20
  !mustConsumeAll
21
- || childParserContext.position === absoluteSliceEnd
21
+ || childParserContext.position === absoluteSliceEnd
22
22
  ),
23
23
  'child parser must consume all input in the slice (%s in total, up to position %s), instead consumed %s up to position %s',
24
24
  sliceEnd,
package/src/smali.ts CHANGED
@@ -2,18 +2,23 @@ import fs from 'node:fs/promises';
2
2
  import { execa } from 'execa';
3
3
  import { temporaryFile } from 'tempy';
4
4
 
5
- export async function smaliClass(smaliStream: AsyncIterable<string>) {
5
+ export async function smaliClass(smaliStream: string | AsyncIterable<string>): Promise<Uint8Array> {
6
6
  const inputFilePath = temporaryFile();
7
7
  const outputFilePath = temporaryFile();
8
8
 
9
9
  await fs.writeFile(inputFilePath, smaliStream);
10
10
 
11
- await execa('smali', [
11
+ const smaliResult = await execa('smali', [
12
12
  'assemble',
13
- '--output', outputFilePath,
13
+ '--output',
14
+ outputFilePath,
14
15
  inputFilePath,
15
16
  ]);
16
17
 
18
+ if (smaliResult.stderr) {
19
+ throw new Error(`smali error: ${smaliResult.stderr}`);
20
+ }
21
+
17
22
  await fs.unlink(inputFilePath);
18
23
 
19
24
  const dex = await fs.readFile(outputFilePath);