@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
@@ -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
- async function stringFromAsyncIterable(asyncIterable: AsyncIterable<string>) {
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 instanceof ParserParsingJoinError) {
58
+ if (isParserParsingJoinError(childError)) {
72
59
  sortChildErrors(childError);
73
60
  }
74
61
  }
75
62
  }
76
63
 
77
- function removeStackLocations(errorStack: string) {
78
- return errorStack.replaceAll(/((at [^\n]+)[\s\n]+)+(at [^\n]+)/g, 'at [LOCATIONS]');
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 instanceof ParserParsingJoinAllError, 'error1 instanceof ParserParsingJoinAllError');
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 instanceof ParserParsingJoinAllError, 'error2 instanceof ParserParsingJoinAllError');
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 instanceof ParserParsingInvariantError, 'error3 instanceof ParserParsingInvariantError');
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 instanceof ParserParsingJoinDeepestError, 'error1 instanceof ParserParsingJoinDeepestError');
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 instanceof ParserParsingJoinDeepestError, 'error2 instanceof ParserParsingJoinDeepestError');
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 instanceof ParserParsingInvariantError, 'error3 instanceof ParserParsingInvariantError');
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 instanceof ParserParsingInvariantError, 'error1 instanceof ParserParsingInvariantError');
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: ParserError,
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
- instanceOf: ParserUnexpectedRemainingInputError,
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.deepEqual(output, 'foo');
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.deepEqual(output, 'foo');
287
- t.deepEqual(await stringFromAsyncIterable(remainingInput!), 'bar');
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.deepEqual(output, 'foo');
348
+ t.is(output, 'foo');
296
349
  t.is(remainingInput, undefined);
297
350
  });
@@ -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
- Child error stacks, indented:␊
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
- Child error stacks, indented:␊
23
+ All child error stacks, indented:␊
24
24
  ParserParsingJoinAllError: No union child parser succeeded.␊
25
- Child error stacks, indented:␊
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.`
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> = (parserContext) => {
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 ParserError) {
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 await withEnrichedParserError(parserContext, inputReader, async () => {
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 await withEnrichedParserError(parserContext, inputReader, async () => {
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;
@@ -10,4 +10,4 @@ export const createParserAccessorParser = <Output, Sequence>(parserAccessor: ()
10
10
  };
11
11
 
12
12
  return parserAccessorParser;
13
- }
13
+ };
@@ -1,5 +1,5 @@
1
- import { createFixedLengthSequenceParser } from "./fixedLengthSequenceParser.js";
2
- import { getParserName, Parser, setParserName } from "./parser.js";
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 { ParserUnexpectedEndOfInputError } from './parserError.js';
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
- instanceOf: ParserUnexpectedEndOfInputError,
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
- instanceOf: ParserUnexpectedEndOfInputError,
55
+ any: true,
56
+ name: 'ParserUnexpectedEndOfInputError',
53
57
  });
54
58
  });
55
59