@futpib/parser 1.0.3 → 1.0.6

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 (262) hide show
  1. package/.claude/settings.local.json +24 -0
  2. package/.github/workflows/main.yml +1 -0
  3. package/build/androidPackageParser.js +30 -32
  4. package/build/arbitraryDalvikBytecode.d.ts +3 -3
  5. package/build/arbitraryDalvikBytecode.js +33 -27
  6. package/build/arbitraryDalvikExecutable.js +55 -17
  7. package/build/arbitraryJava.d.ts +31 -0
  8. package/build/arbitraryJava.js +532 -0
  9. package/build/arbitraryJavaScript.d.ts +3 -0
  10. package/build/arbitraryJavaScript.js +263 -0
  11. package/build/arbitraryJavascript.d.ts +3 -0
  12. package/build/arbitraryJavascript.js +263 -0
  13. package/build/arbitraryZig.d.ts +3 -0
  14. package/build/arbitraryZig.js +240 -0
  15. package/build/arbitraryZipStream.d.ts +1 -1
  16. package/build/arrayParser.js +72 -13
  17. package/build/backsmali.d.ts +4 -3
  18. package/build/backsmali.js +26 -6
  19. package/build/bash.d.ts +89 -0
  20. package/build/bash.js +1 -0
  21. package/build/bashParser.d.ts +6 -0
  22. package/build/bashParser.js +335 -0
  23. package/build/bashParser.test.d.ts +1 -0
  24. package/build/bashParser.test.js +343 -0
  25. package/build/bashParserEdgeCases.test.d.ts +1 -0
  26. package/build/bashParserEdgeCases.test.js +117 -0
  27. package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
  28. package/build/dalvikBytecodeParser/addressConversion.js +334 -0
  29. package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
  30. package/build/dalvikBytecodeParser/formatParsers.js +13 -14
  31. package/build/dalvikBytecodeParser.d.ts +60 -31
  32. package/build/dalvikBytecodeParser.js +92 -35
  33. package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
  34. package/build/dalvikBytecodeParser.test-d.js +268 -0
  35. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
  36. package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
  37. package/build/dalvikBytecodeUnparser.d.ts +2 -2
  38. package/build/dalvikBytecodeUnparser.js +23 -23
  39. package/build/dalvikBytecodeUnparser.test.js +7 -7
  40. package/build/dalvikExecutable.d.ts +3 -3
  41. package/build/dalvikExecutable.test-d.d.ts +1 -0
  42. package/build/dalvikExecutable.test-d.js +59 -0
  43. package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
  44. package/build/dalvikExecutableParser/typedNumbers.js +3 -0
  45. package/build/dalvikExecutableParser.d.ts +2 -1
  46. package/build/dalvikExecutableParser.js +96 -77
  47. package/build/dalvikExecutableParser.test.js +24 -3
  48. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
  49. package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
  50. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
  51. package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
  52. package/build/dalvikExecutableUnparser.d.ts +2 -2
  53. package/build/dalvikExecutableUnparser.test.js +2 -1
  54. package/build/disjunctionParser.d.ts +5 -3
  55. package/build/disjunctionParser.js +79 -17
  56. package/build/disjunctionParser.test-d.d.ts +1 -0
  57. package/build/disjunctionParser.test-d.js +72 -0
  58. package/build/elementSwitchParser.d.ts +4 -0
  59. package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
  60. package/build/elementSwitchParser.test-d.d.ts +1 -0
  61. package/build/elementSwitchParser.test-d.js +44 -0
  62. package/build/exactSequenceParser.d.ts +4 -2
  63. package/build/exactSequenceParser.test-d.d.ts +1 -0
  64. package/build/exactSequenceParser.test-d.js +36 -0
  65. package/build/fetchCid.js +2 -66
  66. package/build/index.d.ts +25 -2
  67. package/build/index.js +23 -1
  68. package/build/index.test.js +16 -1
  69. package/build/inputReader.d.ts +10 -0
  70. package/build/inputReader.js +36 -0
  71. package/build/java.d.ts +502 -0
  72. package/build/java.js +2 -0
  73. package/build/javaKeyStoreParser.js +14 -17
  74. package/build/javaParser.d.ts +51 -0
  75. package/build/javaParser.js +1538 -0
  76. package/build/javaParser.test.d.ts +1 -0
  77. package/build/javaParser.test.js +1287 -0
  78. package/build/javaScript.d.ts +35 -0
  79. package/build/javaScript.js +1 -0
  80. package/build/javaScriptParser.d.ts +9 -0
  81. package/build/javaScriptParser.js +34 -0
  82. package/build/javaScriptUnparser.d.ts +3 -0
  83. package/build/javaScriptUnparser.js +4 -0
  84. package/build/javaScriptUnparser.test.d.ts +1 -0
  85. package/build/javaScriptUnparser.test.js +24 -0
  86. package/build/javaUnparser.d.ts +2 -0
  87. package/build/javaUnparser.js +519 -0
  88. package/build/javaUnparser.test.d.ts +1 -0
  89. package/build/javaUnparser.test.js +24 -0
  90. package/build/javascript.d.ts +35 -0
  91. package/build/javascript.js +1 -0
  92. package/build/javascriptParser.d.ts +9 -0
  93. package/build/javascriptParser.js +34 -0
  94. package/build/javascriptUnparser.d.ts +3 -0
  95. package/build/javascriptUnparser.js +4 -0
  96. package/build/javascriptUnparser.test.d.ts +1 -0
  97. package/build/javascriptUnparser.test.js +24 -0
  98. package/build/jsonParser.js +2 -12
  99. package/build/lazyMessageError.d.ts +3 -0
  100. package/build/lookaheadParser.js +60 -3
  101. package/build/negativeLookaheadParser.js +70 -11
  102. package/build/nonEmptyArrayParser.js +72 -13
  103. package/build/objectParser.d.ts +12 -0
  104. package/build/objectParser.js +31 -0
  105. package/build/objectParser.test-d.d.ts +1 -0
  106. package/build/objectParser.test-d.js +112 -0
  107. package/build/objectParser.test.d.ts +1 -0
  108. package/build/objectParser.test.js +55 -0
  109. package/build/optionalParser.js +69 -10
  110. package/build/parser.d.ts +4 -0
  111. package/build/parser.js +3 -1
  112. package/build/parser.test.js +114 -1
  113. package/build/parserConsumedSequenceParser.js +66 -7
  114. package/build/parserContext.d.ts +6 -0
  115. package/build/parserContext.js +20 -11
  116. package/build/parserError.d.ts +119 -27
  117. package/build/parserError.js +16 -8
  118. package/build/regexpParser.d.ts +2 -0
  119. package/build/regexpParser.js +101 -0
  120. package/build/regexpParser.test.d.ts +1 -0
  121. package/build/regexpParser.test.js +114 -0
  122. package/build/regularExpression.d.ts +63 -0
  123. package/build/regularExpression.js +1 -0
  124. package/build/regularExpressionParser.d.ts +3 -0
  125. package/build/regularExpressionParser.js +600 -0
  126. package/build/regularExpressionParser.test.d.ts +1 -0
  127. package/build/regularExpressionParser.test.js +89 -0
  128. package/build/separatedArrayParser.js +73 -14
  129. package/build/separatedNonEmptyArrayParser.js +73 -14
  130. package/build/sliceBoundedParser.js +62 -5
  131. package/build/smaliParser.d.ts +7 -7
  132. package/build/smaliParser.js +185 -268
  133. package/build/smaliParser.test.js +58 -0
  134. package/build/stringEscapes.d.ts +5 -0
  135. package/build/stringEscapes.js +244 -0
  136. package/build/symbolicExpression.d.ts +29 -0
  137. package/build/symbolicExpression.js +1 -0
  138. package/build/symbolicExpressionParser.d.ts +4 -0
  139. package/build/symbolicExpressionParser.js +123 -0
  140. package/build/symbolicExpressionParser.test.d.ts +1 -0
  141. package/build/symbolicExpressionParser.test.js +289 -0
  142. package/build/terminatedArrayParser.js +113 -38
  143. package/build/terminatedArrayParser.test.js +4 -2
  144. package/build/tupleParser.d.ts +7 -15
  145. package/build/tupleParser.js +1 -0
  146. package/build/unionParser.d.ts +5 -3
  147. package/build/unionParser.js +7 -2
  148. package/build/unionParser.test-d.d.ts +1 -0
  149. package/build/unionParser.test-d.js +72 -0
  150. package/build/unionParser.test.js +10 -11
  151. package/build/zig.d.ts +280 -0
  152. package/build/zig.js +2 -0
  153. package/build/zigParser.d.ts +3 -0
  154. package/build/zigParser.js +1119 -0
  155. package/build/zigParser.test.d.ts +1 -0
  156. package/build/zigParser.test.js +1590 -0
  157. package/build/zigUnparser.d.ts +2 -0
  158. package/build/zigUnparser.js +460 -0
  159. package/build/zigUnparser.test.d.ts +1 -0
  160. package/build/zigUnparser.test.js +24 -0
  161. package/build/zipParser.js +19 -32
  162. package/build/zipUnparser.js +19 -7
  163. package/build/zipUnparser.test.js +1 -1
  164. package/node_modules-@types/s-expression/index.d.ts +5 -0
  165. package/package.json +25 -6
  166. package/src/androidPackageParser.ts +33 -60
  167. package/src/arbitraryDalvikBytecode.ts +39 -31
  168. package/src/arbitraryDalvikExecutable.ts +65 -20
  169. package/src/arbitraryJava.ts +804 -0
  170. package/src/arbitraryJavaScript.ts +410 -0
  171. package/src/arbitraryZig.ts +380 -0
  172. package/src/arrayParser.ts +1 -3
  173. package/src/backsmali.ts +35 -4
  174. package/src/bash.ts +127 -0
  175. package/src/bashParser.test.ts +590 -0
  176. package/src/bashParser.ts +498 -0
  177. package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
  178. package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
  179. package/src/dalvikBytecodeParser.test-d.ts +310 -0
  180. package/src/dalvikBytecodeParser.ts +194 -69
  181. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
  182. package/src/dalvikBytecodeUnparser.test.ts +7 -7
  183. package/src/dalvikBytecodeUnparser.ts +31 -30
  184. package/src/dalvikExecutable.test-d.ts +132 -0
  185. package/src/dalvikExecutable.ts +3 -3
  186. package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
  187. package/src/dalvikExecutableParser.test.ts +37 -3
  188. package/src/dalvikExecutableParser.test.ts.md +163 -2
  189. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  190. package/src/dalvikExecutableParser.ts +121 -139
  191. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
  192. package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
  193. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
  194. package/src/dalvikExecutableUnparser.test.ts +3 -2
  195. package/src/dalvikExecutableUnparser.ts +4 -4
  196. package/src/disjunctionParser.test-d.ts +105 -0
  197. package/src/disjunctionParser.ts +18 -15
  198. package/src/elementSwitchParser.test-d.ts +74 -0
  199. package/src/elementSwitchParser.ts +51 -0
  200. package/src/exactSequenceParser.test-d.ts +43 -0
  201. package/src/exactSequenceParser.ts +13 -8
  202. package/src/fetchCid.ts +2 -76
  203. package/src/index.test.ts +22 -1
  204. package/src/index.ts +119 -2
  205. package/src/inputReader.ts +53 -0
  206. package/src/java.ts +708 -0
  207. package/src/javaKeyStoreParser.ts +18 -32
  208. package/src/javaParser.test.ts +1592 -0
  209. package/src/javaParser.ts +2640 -0
  210. package/src/javaScript.ts +36 -0
  211. package/src/javaScriptParser.ts +57 -0
  212. package/src/javaScriptUnparser.test.ts +37 -0
  213. package/src/javaScriptUnparser.ts +7 -0
  214. package/src/javaUnparser.test.ts +37 -0
  215. package/src/javaUnparser.ts +640 -0
  216. package/src/jsonParser.ts +6 -27
  217. package/src/lookaheadParser.ts +2 -6
  218. package/src/negativeLookaheadParser.ts +1 -3
  219. package/src/nonEmptyArrayParser.ts +1 -3
  220. package/src/objectParser.test-d.ts +152 -0
  221. package/src/objectParser.test.ts +71 -0
  222. package/src/objectParser.ts +69 -0
  223. package/src/optionalParser.ts +1 -3
  224. package/src/parser.test.ts +151 -4
  225. package/src/parser.ts +11 -1
  226. package/src/parserConsumedSequenceParser.ts +2 -4
  227. package/src/parserContext.ts +26 -11
  228. package/src/parserError.ts +17 -3
  229. package/src/regexpParser.test.ts +264 -0
  230. package/src/regexpParser.ts +126 -0
  231. package/src/regularExpression.ts +24 -0
  232. package/src/regularExpressionParser.test.ts +102 -0
  233. package/src/regularExpressionParser.ts +920 -0
  234. package/src/separatedArrayParser.ts +1 -3
  235. package/src/separatedNonEmptyArrayParser.ts +1 -3
  236. package/src/sliceBoundedParser.test.ts +2 -2
  237. package/src/sliceBoundedParser.ts +15 -19
  238. package/src/smaliParser.test.ts +64 -0
  239. package/src/smaliParser.test.ts.md +12 -12
  240. package/src/smaliParser.test.ts.snap +0 -0
  241. package/src/smaliParser.ts +246 -534
  242. package/src/stringEscapes.ts +253 -0
  243. package/src/symbolicExpression.ts +17 -0
  244. package/src/symbolicExpressionParser.test.ts +466 -0
  245. package/src/symbolicExpressionParser.ts +190 -0
  246. package/src/terminatedArrayParser.test.ts +9 -6
  247. package/src/terminatedArrayParser.ts +25 -29
  248. package/src/tupleParser.ts +21 -18
  249. package/src/unionParser.test-d.ts +105 -0
  250. package/src/unionParser.test.ts +18 -17
  251. package/src/unionParser.ts +28 -16
  252. package/src/zig.ts +411 -0
  253. package/src/zigParser.test.ts +1693 -0
  254. package/src/zigParser.ts +1745 -0
  255. package/src/zigUnparser.test.ts +37 -0
  256. package/src/zigUnparser.ts +615 -0
  257. package/src/zipParser.ts +20 -56
  258. package/src/zipUnparser.test.ts +1 -1
  259. package/src/zipUnparser.ts +22 -7
  260. package/tsconfig.json +2 -2
  261. package/build/exactElementSwitchParser.d.ts +0 -3
  262. package/src/exactElementSwitchParser.ts +0 -41
@@ -0,0 +1,1538 @@
1
+ import { setParserName } from './parser.js';
2
+ import { unescapeJavaString } from './stringEscapes.js';
3
+ import { createUnionParser } from './unionParser.js';
4
+ import { createExactSequenceParser } from './exactSequenceParser.js';
5
+ import { promiseCompose } from './promiseCompose.js';
6
+ import { createTupleParser } from './tupleParser.js';
7
+ import { createDisjunctionParser } from './disjunctionParser.js';
8
+ import { createArrayParser } from './arrayParser.js';
9
+ import { createOptionalParser } from './optionalParser.js';
10
+ import { createRegExpParser } from './regexpParser.js';
11
+ import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
12
+ import { createObjectParser } from './objectParser.js';
13
+ // Whitespace (spaces, tabs, newlines)
14
+ const javaWhitespaceParser = promiseCompose(createRegExpParser(/\s+/), match => match[0]);
15
+ const javaOptionalWhitespaceParser = promiseCompose(createRegExpParser(/\s*/), match => match[0]);
16
+ // Line comment: // ...
17
+ const javaLineCommentParser = promiseCompose(createRegExpParser(/\/\/[^\n]*/), match => match[0]);
18
+ // Block comment: /* ... */
19
+ // TODO: proper nested comment handling if needed
20
+ const javaBlockCommentParser = promiseCompose(createRegExpParser(/\/\*[\s\S]*?\*\//), match => match[0]);
21
+ // Comment (line or block)
22
+ const javaCommentParser = createUnionParser([
23
+ javaLineCommentParser,
24
+ javaBlockCommentParser,
25
+ ]);
26
+ // Whitespace or comment
27
+ const javaWhitespaceOrCommentParser = createUnionParser([
28
+ javaWhitespaceParser,
29
+ javaCommentParser,
30
+ ]);
31
+ // Optional whitespace/comments (skippable)
32
+ const javaSkippableParser = createArrayParser(javaWhitespaceOrCommentParser);
33
+ // Identifier: valid Java identifier
34
+ const javaIdentifierParser = promiseCompose(createRegExpParser(/[a-zA-Z_$][a-zA-Z0-9_$]*/), match => match[0]);
35
+ setParserName(javaIdentifierParser, 'javaIdentifierParser');
36
+ // SimpleName: single identifier wrapped in SimpleName node
37
+ const javaSimpleNameParser = createObjectParser({
38
+ type: 'SimpleName',
39
+ identifier: javaIdentifierParser,
40
+ });
41
+ setParserName(javaSimpleNameParser, 'javaSimpleNameParser');
42
+ // Name: qualified name as nested structure (e.g., com.example.Foo)
43
+ // Result is { type: 'Name', identifier: 'Foo', qualifier: { type: 'Name', identifier: 'example', qualifier: { type: 'Name', identifier: 'com' } } }
44
+ const javaNameParser = promiseCompose(createSeparatedNonEmptyArrayParser(javaIdentifierParser, promiseCompose(createTupleParser([
45
+ javaOptionalWhitespaceParser,
46
+ createExactSequenceParser('.'),
47
+ javaOptionalWhitespaceParser,
48
+ ]), () => '.')), parts => {
49
+ // Build nested Name structure from left to right
50
+ // parts = ['com', 'example', 'Foo'] -> nested with 'Foo' at top
51
+ let result = { type: 'Name', identifier: parts[0] };
52
+ for (let i = 1; i < parts.length; i++) {
53
+ result = { type: 'Name', identifier: parts[i], qualifier: result };
54
+ }
55
+ return result;
56
+ });
57
+ setParserName(javaNameParser, 'javaNameParser');
58
+ // Qualified name: com.example.Foo (legacy format with flat parts array)
59
+ const javaQualifiedNameParser = promiseCompose(createSeparatedNonEmptyArrayParser(javaIdentifierParser, promiseCompose(createTupleParser([
60
+ javaOptionalWhitespaceParser,
61
+ createExactSequenceParser('.'),
62
+ javaOptionalWhitespaceParser,
63
+ ]), () => '.')), parts => ({ parts }));
64
+ setParserName(javaQualifiedNameParser, 'javaQualifiedNameParser');
65
+ const javaAnnotationParser = createObjectParser({
66
+ _at: createExactSequenceParser('@'),
67
+ type: 'MarkerAnnotationExpr',
68
+ name: javaNameParser,
69
+ });
70
+ setParserName(javaAnnotationParser, 'javaAnnotationParser');
71
+ // Annotations with trailing whitespace
72
+ const javaAnnotationsParser = createArrayParser(promiseCompose(createTupleParser([
73
+ javaAnnotationParser,
74
+ javaSkippableParser,
75
+ ]), ([annotation]) => annotation));
76
+ const javaPackageDeclarationParserNew = createObjectParser({
77
+ annotations: javaAnnotationsParser,
78
+ _package: createExactSequenceParser('package'),
79
+ _ws1: javaWhitespaceParser,
80
+ type: 'PackageDeclaration',
81
+ name: javaNameParser,
82
+ _ws2: javaOptionalWhitespaceParser,
83
+ _semi: createExactSequenceParser(';'),
84
+ });
85
+ // Legacy package declaration parser (still using old annotation format)
86
+ const javaPackageDeclarationParser = promiseCompose(createTupleParser([
87
+ javaAnnotationsParser,
88
+ createExactSequenceParser('package'),
89
+ javaWhitespaceParser,
90
+ javaQualifiedNameParser,
91
+ javaOptionalWhitespaceParser,
92
+ createExactSequenceParser(';'),
93
+ ]), ([annotations, , , name]) => ({ annotations, name }));
94
+ setParserName(javaPackageDeclarationParser, 'javaPackageDeclarationParser');
95
+ // Import declaration: import [static] com.example.Foo[.*];
96
+ const javaImportDeclarationParser = promiseCompose(createTupleParser([
97
+ createExactSequenceParser('import'),
98
+ javaWhitespaceParser,
99
+ createOptionalParser(promiseCompose(createTupleParser([
100
+ createExactSequenceParser('static'),
101
+ javaWhitespaceParser,
102
+ ]), () => true)),
103
+ javaNameParser,
104
+ createOptionalParser(promiseCompose(createTupleParser([
105
+ javaOptionalWhitespaceParser,
106
+ createExactSequenceParser('.'),
107
+ javaOptionalWhitespaceParser,
108
+ createExactSequenceParser('*'),
109
+ ]), () => true)),
110
+ javaOptionalWhitespaceParser,
111
+ createExactSequenceParser(';'),
112
+ ]), ([, , isStatic, name, isAsterisk]) => ({
113
+ type: 'ImportDeclaration',
114
+ isStatic: isStatic ?? false,
115
+ isAsterisk: isAsterisk ?? false,
116
+ name,
117
+ }));
118
+ setParserName(javaImportDeclarationParser, 'javaImportDeclarationParser');
119
+ // Modifier keywords
120
+ const javaModifierKeywordParser = createDisjunctionParser([
121
+ promiseCompose(createExactSequenceParser('public'), () => 'PUBLIC'),
122
+ promiseCompose(createExactSequenceParser('protected'), () => 'PROTECTED'),
123
+ promiseCompose(createExactSequenceParser('private'), () => 'PRIVATE'),
124
+ promiseCompose(createExactSequenceParser('static'), () => 'STATIC'),
125
+ promiseCompose(createExactSequenceParser('final'), () => 'FINAL'),
126
+ promiseCompose(createExactSequenceParser('abstract'), () => 'ABSTRACT'),
127
+ promiseCompose(createExactSequenceParser('synchronized'), () => 'SYNCHRONIZED'),
128
+ promiseCompose(createExactSequenceParser('native'), () => 'NATIVE'),
129
+ promiseCompose(createExactSequenceParser('transient'), () => 'TRANSIENT'),
130
+ promiseCompose(createExactSequenceParser('volatile'), () => 'VOLATILE'),
131
+ promiseCompose(createExactSequenceParser('strictfp'), () => 'STRICTFP'),
132
+ promiseCompose(createExactSequenceParser('default'), () => 'DEFAULT'),
133
+ promiseCompose(createExactSequenceParser('sealed'), () => 'SEALED'),
134
+ promiseCompose(createExactSequenceParser('non-sealed'), () => 'NON_SEALED'),
135
+ ]);
136
+ const javaModifierParser = createObjectParser({
137
+ type: 'Modifier',
138
+ keyword: javaModifierKeywordParser,
139
+ });
140
+ setParserName(javaModifierParser, 'javaModifierParser');
141
+ const javaPrimitiveTypeParser = createDisjunctionParser([
142
+ promiseCompose(createExactSequenceParser('boolean'), () => ({ type: 'PrimitiveType', type_: 'BOOLEAN', annotations: [] })),
143
+ promiseCompose(createExactSequenceParser('byte'), () => ({ type: 'PrimitiveType', type_: 'BYTE', annotations: [] })),
144
+ promiseCompose(createExactSequenceParser('char'), () => ({ type: 'PrimitiveType', type_: 'CHAR', annotations: [] })),
145
+ promiseCompose(createExactSequenceParser('double'), () => ({ type: 'PrimitiveType', type_: 'DOUBLE', annotations: [] })),
146
+ promiseCompose(createExactSequenceParser('float'), () => ({ type: 'PrimitiveType', type_: 'FLOAT', annotations: [] })),
147
+ promiseCompose(createExactSequenceParser('int'), () => ({ type: 'PrimitiveType', type_: 'INT', annotations: [] })),
148
+ promiseCompose(createExactSequenceParser('long'), () => ({ type: 'PrimitiveType', type_: 'LONG', annotations: [] })),
149
+ promiseCompose(createExactSequenceParser('short'), () => ({ type: 'PrimitiveType', type_: 'SHORT', annotations: [] })),
150
+ ]);
151
+ setParserName(javaPrimitiveTypeParser, 'javaPrimitiveTypeParser');
152
+ const javaVoidTypeParser = createObjectParser({
153
+ _void: createExactSequenceParser('void'),
154
+ type: 'VoidType',
155
+ annotations: [],
156
+ });
157
+ setParserName(javaVoidTypeParser, 'javaVoidTypeParser');
158
+ // Forward declaration for recursive type parsing
159
+ let javaTypeParser;
160
+ const javaWildcardTypeParser = promiseCompose(createTupleParser([
161
+ createExactSequenceParser('?'),
162
+ javaSkippableParser,
163
+ createOptionalParser(createUnionParser([
164
+ promiseCompose(createTupleParser([
165
+ createExactSequenceParser('extends'),
166
+ javaSkippableParser,
167
+ (ctx) => javaTypeParser(ctx),
168
+ ]), ([, , type]) => ({ extendedType: type })),
169
+ promiseCompose(createTupleParser([
170
+ createExactSequenceParser('super'),
171
+ javaSkippableParser,
172
+ (ctx) => javaTypeParser(ctx),
173
+ ]), ([, , type]) => ({ superType: type })),
174
+ ])),
175
+ ]), ([, , bounds]) => ({
176
+ type: 'WildcardType',
177
+ annotations: [],
178
+ ...(bounds ?? {}),
179
+ }));
180
+ setParserName(javaWildcardTypeParser, 'javaWildcardTypeParser');
181
+ // Type argument: either a type or a wildcard
182
+ const javaTypeArgumentParser = createUnionParser([
183
+ javaWildcardTypeParser,
184
+ (ctx) => javaTypeParser(ctx),
185
+ ]);
186
+ setParserName(javaTypeArgumentParser, 'javaTypeArgumentParser');
187
+ // Type arguments: <T, U, V> or <?, ? extends Foo>
188
+ const javaTypeArgumentsParser = promiseCompose(createTupleParser([
189
+ createExactSequenceParser('<'),
190
+ javaSkippableParser,
191
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
192
+ javaTypeArgumentParser,
193
+ javaSkippableParser,
194
+ ]), ([type]) => type), promiseCompose(createTupleParser([
195
+ createExactSequenceParser(','),
196
+ javaSkippableParser,
197
+ ]), () => ',')),
198
+ javaSkippableParser,
199
+ createExactSequenceParser('>'),
200
+ ]), ([, , types]) => types);
201
+ setParserName(javaTypeArgumentsParser, 'javaTypeArgumentsParser');
202
+ const javaTypeParameterParser = promiseCompose(createTupleParser([
203
+ javaSimpleNameParser,
204
+ javaSkippableParser,
205
+ createOptionalParser(promiseCompose(createTupleParser([
206
+ createExactSequenceParser('extends'),
207
+ javaSkippableParser,
208
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
209
+ (ctx) => javaTypeParser(ctx),
210
+ javaSkippableParser,
211
+ ]), ([type]) => type), promiseCompose(createTupleParser([
212
+ createExactSequenceParser('&'),
213
+ javaSkippableParser,
214
+ ]), () => '&')),
215
+ ]), ([, , bounds]) => bounds)),
216
+ ]), ([name, , typeBound]) => ({
217
+ type: 'TypeParameter',
218
+ annotations: [], // TODO: parse type parameter annotations
219
+ name,
220
+ typeBound: typeBound ?? [],
221
+ }));
222
+ setParserName(javaTypeParameterParser, 'javaTypeParameterParser');
223
+ // Type parameters: <T>, <T, U>, <T extends Foo>
224
+ const javaTypeParametersParser = promiseCompose(createTupleParser([
225
+ createExactSequenceParser('<'),
226
+ javaSkippableParser,
227
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
228
+ javaTypeParameterParser,
229
+ javaSkippableParser,
230
+ ]), ([param]) => param), promiseCompose(createTupleParser([
231
+ createExactSequenceParser(','),
232
+ javaSkippableParser,
233
+ ]), () => ',')),
234
+ javaSkippableParser,
235
+ createExactSequenceParser('>'),
236
+ ]), ([, , params]) => params);
237
+ setParserName(javaTypeParametersParser, 'javaTypeParametersParser');
238
+ // ClassOrInterfaceType: Foo, List<T>, Outer.Inner, Map<K, V>
239
+ // Forward declaration for recursive scope
240
+ let javaClassOrInterfaceTypeParser;
241
+ // Parser for a single type segment (name with optional type arguments)
242
+ const javaTypeSegmentParser = promiseCompose(createTupleParser([
243
+ javaSimpleNameParser,
244
+ javaSkippableParser,
245
+ createOptionalParser(javaTypeArgumentsParser),
246
+ ]), ([name, , typeArguments]) => ({
247
+ name,
248
+ ...(typeArguments ? { typeArguments } : {}),
249
+ }));
250
+ setParserName(javaTypeSegmentParser, 'javaTypeSegmentParser');
251
+ // Full ClassOrInterfaceType with optional scope: Outer.Inner or just Foo
252
+ javaClassOrInterfaceTypeParser = promiseCompose(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
253
+ javaTypeSegmentParser,
254
+ javaSkippableParser,
255
+ ]), ([segment]) => segment), promiseCompose(createTupleParser([
256
+ createExactSequenceParser('.'),
257
+ javaSkippableParser,
258
+ ]), () => '.')), (segments) => {
259
+ // Build the type from segments: [Outer, Inner] -> { scope: Outer, name: Inner }
260
+ let result;
261
+ for (const segment of segments) {
262
+ if (result === undefined) {
263
+ result = {
264
+ type: 'ClassOrInterfaceType',
265
+ name: segment.name,
266
+ ...(segment.typeArguments ? { typeArguments: segment.typeArguments } : {}),
267
+ annotations: [],
268
+ };
269
+ }
270
+ else {
271
+ result = {
272
+ type: 'ClassOrInterfaceType',
273
+ scope: result,
274
+ name: segment.name,
275
+ ...(segment.typeArguments ? { typeArguments: segment.typeArguments } : {}),
276
+ annotations: [],
277
+ };
278
+ }
279
+ }
280
+ return result;
281
+ });
282
+ setParserName(javaClassOrInterfaceTypeParser, 'javaClassOrInterfaceTypeParser');
283
+ // Base type (without array brackets)
284
+ const javaBaseTypeParser = createDisjunctionParser([
285
+ javaPrimitiveTypeParser,
286
+ javaVoidTypeParser,
287
+ javaClassOrInterfaceTypeParser,
288
+ ]);
289
+ // Array brackets
290
+ const javaArrayBracketsParser = createArrayParser(promiseCompose(createTupleParser([
291
+ javaSkippableParser,
292
+ createExactSequenceParser('['),
293
+ javaSkippableParser,
294
+ createExactSequenceParser(']'),
295
+ ]), () => []));
296
+ // Full type with optional array brackets
297
+ javaTypeParser = promiseCompose(createTupleParser([
298
+ javaBaseTypeParser,
299
+ javaArrayBracketsParser,
300
+ ]), ([baseType, brackets]) => {
301
+ let result = baseType;
302
+ for (const _ of brackets) {
303
+ result = {
304
+ type: 'ArrayType',
305
+ componentType: result,
306
+ origin: 'TYPE',
307
+ annotations: [],
308
+ };
309
+ }
310
+ return result;
311
+ });
312
+ setParserName(javaTypeParser, 'javaTypeParser');
313
+ // Modifiers with trailing whitespace
314
+ const javaModifiersParser = createArrayParser(promiseCompose(createTupleParser([
315
+ javaModifierParser,
316
+ javaSkippableParser,
317
+ ]), ([modifier]) => modifier));
318
+ // Skip balanced braces (for skipping method/block bodies)
319
+ const javaSkipBalancedBracesParser = promiseCompose(createRegExpParser(/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}/), match => match[0]);
320
+ const javaParameterParser = promiseCompose(createTupleParser([
321
+ javaAnnotationsParser,
322
+ javaModifiersParser,
323
+ javaTypeParser,
324
+ javaSkippableParser,
325
+ createOptionalParser(createExactSequenceParser('...')), // varargs
326
+ javaSkippableParser,
327
+ javaSimpleNameParser,
328
+ ]), ([annotations, modifiers, type_, , varArgs, , name]) => ({
329
+ type: 'Parameter',
330
+ modifiers,
331
+ annotations,
332
+ type_,
333
+ isVarArgs: varArgs !== undefined,
334
+ varArgsAnnotations: [],
335
+ name,
336
+ }));
337
+ setParserName(javaParameterParser, 'javaParameterParser');
338
+ // Parameter list: (param1, param2, ...)
339
+ const javaParameterListParser = promiseCompose(createTupleParser([
340
+ createExactSequenceParser('('),
341
+ javaSkippableParser,
342
+ createOptionalParser(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
343
+ javaParameterParser,
344
+ javaSkippableParser,
345
+ ]), ([param]) => param), promiseCompose(createTupleParser([
346
+ createExactSequenceParser(','),
347
+ javaSkippableParser,
348
+ ]), () => ','))),
349
+ javaSkippableParser,
350
+ createExactSequenceParser(')'),
351
+ ]), ([, , params]) => params ?? []);
352
+ setParserName(javaParameterListParser, 'javaParameterListParser');
353
+ // Throws clause: throws Exception1, Exception2
354
+ const javaThrowsClauseParser = promiseCompose(createTupleParser([
355
+ createExactSequenceParser('throws'),
356
+ javaWhitespaceParser,
357
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
358
+ javaClassOrInterfaceTypeParser,
359
+ javaSkippableParser,
360
+ ]), ([type]) => type), promiseCompose(createTupleParser([
361
+ createExactSequenceParser(','),
362
+ javaSkippableParser,
363
+ ]), () => ',')),
364
+ ]), ([, , types]) => types);
365
+ setParserName(javaThrowsClauseParser, 'javaThrowsClauseParser');
366
+ // Implements clause: implements Interface1, Interface2
367
+ const javaImplementsClauseParser = promiseCompose(createTupleParser([
368
+ createExactSequenceParser('implements'),
369
+ javaWhitespaceParser,
370
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
371
+ javaClassOrInterfaceTypeParser,
372
+ javaSkippableParser,
373
+ ]), ([type]) => type), promiseCompose(createTupleParser([
374
+ createExactSequenceParser(','),
375
+ javaSkippableParser,
376
+ ]), () => ',')),
377
+ ]), ([, , types]) => types);
378
+ setParserName(javaImplementsClauseParser, 'javaImplementsClauseParser');
379
+ // Extends clause: extends Parent
380
+ const javaExtendsClauseParser = promiseCompose(createTupleParser([
381
+ createExactSequenceParser('extends'),
382
+ javaWhitespaceParser,
383
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
384
+ javaClassOrInterfaceTypeParser,
385
+ javaSkippableParser,
386
+ ]), ([type]) => type), promiseCompose(createTupleParser([
387
+ createExactSequenceParser(','),
388
+ javaSkippableParser,
389
+ ]), () => ',')),
390
+ ]), ([, , types]) => types);
391
+ setParserName(javaExtendsClauseParser, 'javaExtendsClauseParser');
392
+ // Forward declaration - will be defined after expression parsers
393
+ let javaStatementParser;
394
+ let javaBlockStmtParserWithStatements;
395
+ // Simple block parser that skips content (used during initial parsing)
396
+ const javaBlockStmtParser = createObjectParser({
397
+ _content: javaSkipBalancedBracesParser,
398
+ type: 'BlockStmt',
399
+ statements: [], // Will be replaced by javaBlockStmtParserWithStatements
400
+ });
401
+ setParserName(javaBlockStmtParser, 'javaBlockStmtParser');
402
+ const javaMethodDeclarationParser = promiseCompose(createTupleParser([
403
+ javaAnnotationsParser,
404
+ javaModifiersParser,
405
+ createOptionalParser(promiseCompose(createTupleParser([
406
+ javaTypeParametersParser,
407
+ javaSkippableParser,
408
+ ]), ([params]) => params)),
409
+ javaTypeParser,
410
+ javaSkippableParser,
411
+ javaSimpleNameParser,
412
+ javaSkippableParser,
413
+ javaParameterListParser,
414
+ javaSkippableParser,
415
+ createOptionalParser(promiseCompose(createTupleParser([
416
+ javaThrowsClauseParser,
417
+ javaSkippableParser,
418
+ ]), ([throws]) => throws)),
419
+ createUnionParser([
420
+ (ctx) => javaBlockStmtParserWithStatements(ctx),
421
+ promiseCompose(createExactSequenceParser(';'), () => undefined),
422
+ ]),
423
+ ]), ([annotations, modifiers, typeParameters, type_, , name, , parameters, , thrownExceptions, body]) => ({
424
+ type: 'MethodDeclaration',
425
+ modifiers,
426
+ annotations,
427
+ typeParameters: typeParameters ?? [],
428
+ type_,
429
+ name,
430
+ parameters,
431
+ thrownExceptions: thrownExceptions ?? [],
432
+ ...(body ? { body } : {}),
433
+ }));
434
+ setParserName(javaMethodDeclarationParser, 'javaMethodDeclarationParser');
435
+ // Expression parsers
436
+ // Forward declaration for recursive expression parsing
437
+ let javaExpressionParser;
438
+ const javaNameExprParser = createObjectParser({
439
+ type: 'NameExpr',
440
+ name: javaSimpleNameParser,
441
+ });
442
+ setParserName(javaNameExprParser, 'javaNameExprParser');
443
+ const javaStringLiteralExprParser = promiseCompose(createRegExpParser(/"(?:[^"\\]|\\.)*"/), match => ({
444
+ type: 'StringLiteralExpr',
445
+ value: unescapeJavaString(match[0].slice(1, -1)),
446
+ }));
447
+ setParserName(javaStringLiteralExprParser, 'javaStringLiteralExprParser');
448
+ const javaIntegerLiteralExprParser = promiseCompose(createRegExpParser(/(?:0x[0-9a-fA-F]+|0b[01]+|0[0-7]*|[1-9][0-9]*)[lL]?/), match => ({
449
+ type: 'IntegerLiteralExpr',
450
+ value: match[0],
451
+ }));
452
+ setParserName(javaIntegerLiteralExprParser, 'javaIntegerLiteralExprParser');
453
+ const javaNullLiteralExprParser = createObjectParser({
454
+ _null: createExactSequenceParser('null'),
455
+ type: 'NullLiteralExpr',
456
+ });
457
+ setParserName(javaNullLiteralExprParser, 'javaNullLiteralExprParser');
458
+ const javaBooleanLiteralExprParser = createUnionParser([
459
+ promiseCompose(createExactSequenceParser('true'), () => ({ type: 'BooleanLiteralExpr', value: true })),
460
+ promiseCompose(createExactSequenceParser('false'), () => ({ type: 'BooleanLiteralExpr', value: false })),
461
+ ]);
462
+ setParserName(javaBooleanLiteralExprParser, 'javaBooleanLiteralExprParser');
463
+ const javaTypeExprParser = createObjectParser({
464
+ type: 'TypeExpr',
465
+ type_: javaClassOrInterfaceTypeParser,
466
+ });
467
+ setParserName(javaTypeExprParser, 'javaTypeExprParser');
468
+ const javaMethodReferenceExprParser = createObjectParser({
469
+ type: 'MethodReferenceExpr',
470
+ scope: javaTypeExprParser,
471
+ _ws1: javaSkippableParser,
472
+ _colons: createExactSequenceParser('::'),
473
+ _ws2: javaSkippableParser,
474
+ identifier: javaIdentifierParser,
475
+ });
476
+ setParserName(javaMethodReferenceExprParser, 'javaMethodReferenceExprParser');
477
+ // Argument list: (arg1, arg2, ...)
478
+ const javaArgumentListParser = promiseCompose(createTupleParser([
479
+ createExactSequenceParser('('),
480
+ javaSkippableParser,
481
+ createOptionalParser(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
482
+ (ctx) => javaExpressionParser(ctx),
483
+ javaSkippableParser,
484
+ ]), ([expr]) => expr), promiseCompose(createTupleParser([
485
+ createExactSequenceParser(','),
486
+ javaSkippableParser,
487
+ ]), () => ','))),
488
+ javaSkippableParser,
489
+ createExactSequenceParser(')'),
490
+ ]), ([, , args]) => args ?? []);
491
+ setParserName(javaArgumentListParser, 'javaArgumentListParser');
492
+ // Simple method call without scope: foo(args)
493
+ const javaSimpleMethodCallExprParser = createObjectParser({
494
+ type: 'MethodCallExpr',
495
+ name: javaSimpleNameParser,
496
+ _ws1: javaSkippableParser,
497
+ arguments: javaArgumentListParser,
498
+ });
499
+ setParserName(javaSimpleMethodCallExprParser, 'javaSimpleMethodCallExprParser');
500
+ // ObjectCreationExpr: new ClassName(args) or new ClassName<>(args) (diamond)
501
+ const javaObjectCreationExprParser = promiseCompose(createTupleParser([
502
+ createExactSequenceParser('new'),
503
+ javaWhitespaceParser, // Must have whitespace after 'new' to avoid matching 'newFoo()' as method call
504
+ javaClassOrInterfaceTypeParser,
505
+ javaSkippableParser,
506
+ // Optional diamond operator <>
507
+ createOptionalParser(promiseCompose(createTupleParser([
508
+ createExactSequenceParser('<'),
509
+ javaSkippableParser,
510
+ createExactSequenceParser('>'),
511
+ javaSkippableParser,
512
+ ]), () => true)),
513
+ javaArgumentListParser,
514
+ ]), ([, , type_, , diamond, args]) => ({
515
+ type: 'ObjectCreationExpr',
516
+ type_: diamond ? {
517
+ ...type_,
518
+ typeArguments: [], // Diamond means empty type arguments
519
+ } : type_,
520
+ arguments: args,
521
+ }));
522
+ setParserName(javaObjectCreationExprParser, 'javaObjectCreationExprParser');
523
+ const javaThisExprParser = createObjectParser({
524
+ _this: createExactSequenceParser('this'),
525
+ type: 'ThisExpr',
526
+ });
527
+ setParserName(javaThisExprParser, 'javaThisExprParser');
528
+ // Forward declaration - will be defined later after primary expressions
529
+ let javaCastExprParser;
530
+ const javaEnclosedExprParser = createObjectParser({
531
+ _open: createExactSequenceParser('('),
532
+ _ws1: javaSkippableParser,
533
+ type: 'EnclosedExpr',
534
+ inner: (ctx) => javaExpressionParser(ctx),
535
+ _ws2: javaSkippableParser,
536
+ _close: createExactSequenceParser(')'),
537
+ });
538
+ setParserName(javaEnclosedExprParser, 'javaEnclosedExprParser');
539
+ // Lambda parameter (can be just identifier or Type identifier)
540
+ const javaLambdaParameterParser = promiseCompose(createTupleParser([
541
+ createOptionalParser(promiseCompose(createTupleParser([
542
+ javaTypeParser,
543
+ javaWhitespaceParser,
544
+ ]), ([type_]) => type_)),
545
+ javaSimpleNameParser,
546
+ ]), ([type_, name]) => ({
547
+ type: 'Parameter',
548
+ annotations: [],
549
+ modifiers: [],
550
+ isVarArgs: false,
551
+ varArgsAnnotations: [],
552
+ name,
553
+ type_: type_ ?? { type: 'UnknownType', annotations: [] },
554
+ }));
555
+ setParserName(javaLambdaParameterParser, 'javaLambdaParameterParser');
556
+ // Lambda expression: (params) -> body or x -> body
557
+ // LambdaExpr with parenthesized parameters
558
+ const javaLambdaWithParensParser = promiseCompose(createTupleParser([
559
+ createExactSequenceParser('('),
560
+ javaSkippableParser,
561
+ createOptionalParser(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
562
+ javaLambdaParameterParser,
563
+ javaSkippableParser,
564
+ ]), ([param]) => param), promiseCompose(createTupleParser([
565
+ createExactSequenceParser(','),
566
+ javaSkippableParser,
567
+ ]), () => ','))),
568
+ createExactSequenceParser(')'),
569
+ javaSkippableParser,
570
+ createExactSequenceParser('->'),
571
+ javaSkippableParser,
572
+ createDisjunctionParser([
573
+ (ctx) => javaBlockStmtParserWithStatements(ctx), // Block body
574
+ (ctx) => javaExpressionParser(ctx), // Expression body
575
+ ]),
576
+ ]), ([, , params, , , , , body]) => ({
577
+ type: 'LambdaExpr',
578
+ parameters: params ?? [],
579
+ // Wrap expression body in ExpressionStmt to match javaparser format
580
+ body: body && typeof body === 'object' && 'type' in body && body.type === 'BlockStmt'
581
+ ? body
582
+ : { type: 'ExpressionStmt', expression: body },
583
+ isEnclosingParameters: true,
584
+ }));
585
+ setParserName(javaLambdaWithParensParser, 'javaLambdaWithParensParser');
586
+ // Lambda with single identifier parameter (no parens): x -> body
587
+ const javaLambdaSingleParamParser = promiseCompose(createTupleParser([
588
+ javaSimpleNameParser,
589
+ javaSkippableParser,
590
+ createExactSequenceParser('->'),
591
+ javaSkippableParser,
592
+ createDisjunctionParser([
593
+ (ctx) => javaBlockStmtParserWithStatements(ctx), // Block body
594
+ (ctx) => javaExpressionParser(ctx), // Expression body
595
+ ]),
596
+ ]), ([param, , , , body]) => ({
597
+ type: 'LambdaExpr',
598
+ parameters: [{
599
+ type: 'Parameter',
600
+ annotations: [],
601
+ modifiers: [],
602
+ isVarArgs: false,
603
+ varArgsAnnotations: [],
604
+ name: param,
605
+ type_: { type: 'UnknownType', annotations: [] },
606
+ }],
607
+ // Wrap expression body in ExpressionStmt to match javaparser format
608
+ body: body && typeof body === 'object' && 'type' in body && body.type === 'BlockStmt'
609
+ ? body
610
+ : { type: 'ExpressionStmt', expression: body },
611
+ isEnclosingParameters: false,
612
+ }));
613
+ setParserName(javaLambdaSingleParamParser, 'javaLambdaSingleParamParser');
614
+ // Primary expression (without method calls chained)
615
+ const javaPrimaryExprParser = createDisjunctionParser([
616
+ javaStringLiteralExprParser,
617
+ javaIntegerLiteralExprParser,
618
+ javaNullLiteralExprParser,
619
+ javaBooleanLiteralExprParser,
620
+ javaThisExprParser, // this - must come before NameExpr
621
+ javaObjectCreationExprParser, // new Foo() - must come before NameExpr
622
+ javaMethodReferenceExprParser,
623
+ javaSimpleMethodCallExprParser, // foo() - must come before NameExpr
624
+ (ctx) => javaCastExprParser(ctx), // Cast - must come before enclosed
625
+ javaLambdaWithParensParser, // (x, y) -> expr - must come before enclosed
626
+ javaEnclosedExprParser, // (expr) - parenthesized expressions
627
+ javaLambdaSingleParamParser, // x -> expr - must come before NameExpr
628
+ javaNameExprParser, // Must be last since it matches any identifier
629
+ ]);
630
+ setParserName(javaPrimaryExprParser, 'javaPrimaryExprParser');
631
+ // Helper to convert a NameExpr to a ClassOrInterfaceType for ClassExpr
632
+ function nameExprToType(expr) {
633
+ if (expr && typeof expr === 'object' && 'type' in expr) {
634
+ if (expr.type === 'NameExpr') {
635
+ const nameExpr = expr;
636
+ return {
637
+ type: 'ClassOrInterfaceType',
638
+ name: nameExpr.name,
639
+ annotations: [],
640
+ };
641
+ }
642
+ if (expr.type === 'FieldAccessExpr') {
643
+ const fieldAccess = expr;
644
+ return {
645
+ type: 'ClassOrInterfaceType',
646
+ scope: nameExprToType(fieldAccess.scope),
647
+ name: fieldAccess.name,
648
+ annotations: [],
649
+ };
650
+ }
651
+ }
652
+ return expr;
653
+ }
654
+ // Expression with optional member access chain: expr.field, expr.method(args), expr::method, expr[index]
655
+ const javaMemberAccessExprParser = promiseCompose(createTupleParser([
656
+ javaPrimaryExprParser,
657
+ createArrayParser(createDisjunctionParser([
658
+ // Method reference: ::identifier
659
+ promiseCompose(createTupleParser([
660
+ javaSkippableParser,
661
+ createExactSequenceParser('::'),
662
+ javaSkippableParser,
663
+ javaIdentifierParser,
664
+ ]), ([, , , identifier]) => ({ type: 'methodReference', identifier })),
665
+ // Array access: [index]
666
+ promiseCompose(createTupleParser([
667
+ javaSkippableParser,
668
+ createExactSequenceParser('['),
669
+ javaSkippableParser,
670
+ (ctx) => javaExpressionParser(ctx),
671
+ javaSkippableParser,
672
+ createExactSequenceParser(']'),
673
+ ]), ([, , , index]) => ({ type: 'arrayAccess', index })),
674
+ // Class literal: .class
675
+ promiseCompose(createTupleParser([
676
+ javaSkippableParser,
677
+ createExactSequenceParser('.'),
678
+ javaSkippableParser,
679
+ createExactSequenceParser('class'),
680
+ ]), () => ({ type: 'classLiteral' })),
681
+ // Field access or method call: .name[(args)]
682
+ promiseCompose(createTupleParser([
683
+ javaSkippableParser,
684
+ createExactSequenceParser('.'),
685
+ javaSkippableParser,
686
+ javaSimpleNameParser,
687
+ javaSkippableParser,
688
+ createOptionalParser(javaArgumentListParser),
689
+ ]), ([, , , name, , args]) => ({ type: 'member', name, arguments: args })),
690
+ ])),
691
+ ]), ([primary, members]) => {
692
+ let result = primary;
693
+ for (const member of members) {
694
+ if (member.type === 'methodReference') {
695
+ result = {
696
+ type: 'MethodReferenceExpr',
697
+ scope: result,
698
+ identifier: member.identifier,
699
+ };
700
+ }
701
+ else if (member.type === 'arrayAccess') {
702
+ result = {
703
+ type: 'ArrayAccessExpr',
704
+ name: result,
705
+ index: member.index,
706
+ };
707
+ }
708
+ else if (member.type === 'classLiteral') {
709
+ // Convert the scope to a type for ClassExpr
710
+ result = {
711
+ type: 'ClassExpr',
712
+ type_: nameExprToType(result),
713
+ };
714
+ }
715
+ else if (member.arguments !== undefined) {
716
+ result = {
717
+ type: 'MethodCallExpr',
718
+ scope: result,
719
+ name: member.name,
720
+ arguments: member.arguments,
721
+ };
722
+ }
723
+ else {
724
+ result = {
725
+ type: 'FieldAccessExpr',
726
+ scope: result,
727
+ name: member.name,
728
+ };
729
+ }
730
+ }
731
+ return result;
732
+ });
733
+ setParserName(javaMemberAccessExprParser, 'javaMemberAccessExprParser');
734
+ // Postfix expression: expr++ or expr--
735
+ const javaPostfixExprParser = promiseCompose(createTupleParser([
736
+ javaMemberAccessExprParser,
737
+ createOptionalParser(createDisjunctionParser([
738
+ promiseCompose(createExactSequenceParser('++'), () => 'POSTFIX_INCREMENT'),
739
+ promiseCompose(createExactSequenceParser('--'), () => 'POSTFIX_DECREMENT'),
740
+ ])),
741
+ ]), ([expr, operator]) => {
742
+ if (operator) {
743
+ return {
744
+ type: 'UnaryExpr',
745
+ operator,
746
+ expression: expr,
747
+ };
748
+ }
749
+ return expr;
750
+ });
751
+ setParserName(javaPostfixExprParser, 'javaPostfixExprParser');
752
+ // Define cast expression: (Type) expr
753
+ javaCastExprParser = createObjectParser({
754
+ _open: createExactSequenceParser('('),
755
+ _ws1: javaSkippableParser,
756
+ type: 'CastExpr',
757
+ type_: javaTypeParser,
758
+ _ws2: javaSkippableParser,
759
+ _close: createExactSequenceParser(')'),
760
+ _ws3: javaSkippableParser,
761
+ expression: javaMemberAccessExprParser,
762
+ });
763
+ setParserName(javaCastExprParser, 'javaCastExprParser');
764
+ const javaUnaryExprParser = createDisjunctionParser([
765
+ // Pre-increment/decrement: ++x, --x
766
+ promiseCompose(createTupleParser([
767
+ createDisjunctionParser([
768
+ promiseCompose(createExactSequenceParser('++'), () => 'PREFIX_INCREMENT'),
769
+ promiseCompose(createExactSequenceParser('--'), () => 'PREFIX_DECREMENT'),
770
+ ]),
771
+ javaSkippableParser,
772
+ (ctx) => javaUnaryExprParser(ctx),
773
+ ]), ([operator, , expression]) => ({
774
+ type: 'UnaryExpr',
775
+ operator,
776
+ expression,
777
+ })),
778
+ // Unary minus, plus, not
779
+ promiseCompose(createTupleParser([
780
+ createDisjunctionParser([
781
+ promiseCompose(createExactSequenceParser('-'), () => 'MINUS'),
782
+ promiseCompose(createExactSequenceParser('+'), () => 'PLUS'),
783
+ promiseCompose(createExactSequenceParser('!'), () => 'LOGICAL_COMPLEMENT'),
784
+ ]),
785
+ javaSkippableParser,
786
+ (ctx) => javaUnaryExprParser(ctx), // Recursive for --x, !!x, etc.
787
+ ]), ([operator, , expression]) => ({
788
+ type: 'UnaryExpr',
789
+ operator,
790
+ expression,
791
+ })),
792
+ // Non-unary (postfix/primary/member access)
793
+ javaPostfixExprParser,
794
+ ]);
795
+ setParserName(javaUnaryExprParser, 'javaUnaryExprParser');
796
+ // Multiplicative operator (*, /, %)
797
+ const javaMultiplicativeOperatorParser = createDisjunctionParser([
798
+ promiseCompose(createExactSequenceParser('*'), () => 'MULTIPLY'),
799
+ promiseCompose(createExactSequenceParser('/'), () => 'DIVIDE'),
800
+ promiseCompose(createExactSequenceParser('%'), () => 'REMAINDER'),
801
+ ]);
802
+ // Multiplicative expression
803
+ const javaMultiplicativeExprParser = promiseCompose(createTupleParser([
804
+ javaUnaryExprParser,
805
+ createArrayParser(promiseCompose(createTupleParser([
806
+ javaSkippableParser,
807
+ javaMultiplicativeOperatorParser,
808
+ javaSkippableParser,
809
+ javaUnaryExprParser,
810
+ ]), ([, operator, , right]) => ({ operator, right }))),
811
+ ]), ([left, operations]) => {
812
+ let result = left;
813
+ for (const op of operations) {
814
+ result = {
815
+ type: 'BinaryExpr',
816
+ left: result,
817
+ right: op.right,
818
+ operator: op.operator,
819
+ };
820
+ }
821
+ return result;
822
+ });
823
+ setParserName(javaMultiplicativeExprParser, 'javaMultiplicativeExprParser');
824
+ // Additive operator (+, -)
825
+ const javaAdditiveOperatorParser = createDisjunctionParser([
826
+ promiseCompose(createExactSequenceParser('+'), () => 'PLUS'),
827
+ promiseCompose(createExactSequenceParser('-'), () => 'MINUS'),
828
+ ]);
829
+ // Additive expression (handles string concatenation and arithmetic)
830
+ const javaAdditiveExprParser = promiseCompose(createTupleParser([
831
+ javaMultiplicativeExprParser,
832
+ createArrayParser(promiseCompose(createTupleParser([
833
+ javaSkippableParser,
834
+ javaAdditiveOperatorParser,
835
+ javaSkippableParser,
836
+ javaUnaryExprParser,
837
+ ]), ([, operator, , right]) => ({ operator, right }))),
838
+ ]), ([left, operations]) => {
839
+ let result = left;
840
+ for (const op of operations) {
841
+ result = {
842
+ type: 'BinaryExpr',
843
+ left: result,
844
+ right: op.right,
845
+ operator: op.operator,
846
+ };
847
+ }
848
+ return result;
849
+ });
850
+ setParserName(javaAdditiveExprParser, 'javaAdditiveExprParser');
851
+ // Relational expression with instanceof
852
+ const javaRelationalExprParser = promiseCompose(createTupleParser([
853
+ javaAdditiveExprParser,
854
+ createOptionalParser(promiseCompose(createTupleParser([
855
+ javaSkippableParser,
856
+ createExactSequenceParser('instanceof'),
857
+ javaWhitespaceParser,
858
+ javaTypeParser,
859
+ ]), ([, , , type_]) => ({ type: 'instanceof', type_ }))),
860
+ ]), ([expr, instanceOf]) => {
861
+ if (instanceOf) {
862
+ return {
863
+ type: 'InstanceOfExpr',
864
+ expression: expr,
865
+ type_: instanceOf.type_,
866
+ };
867
+ }
868
+ return expr;
869
+ });
870
+ setParserName(javaRelationalExprParser, 'javaRelationalExprParser');
871
+ // Comparison operator
872
+ const javaComparisonOperatorParser = createDisjunctionParser([
873
+ promiseCompose(createExactSequenceParser('<='), () => 'LESS_EQUALS'),
874
+ promiseCompose(createExactSequenceParser('>='), () => 'GREATER_EQUALS'),
875
+ promiseCompose(createExactSequenceParser('=='), () => 'EQUALS'),
876
+ promiseCompose(createExactSequenceParser('!='), () => 'NOT_EQUALS'),
877
+ promiseCompose(createExactSequenceParser('<'), () => 'LESS'),
878
+ promiseCompose(createExactSequenceParser('>'), () => 'GREATER'),
879
+ ]);
880
+ // Comparison expression (relational and equality)
881
+ const javaComparisonExprParser = promiseCompose(createTupleParser([
882
+ javaRelationalExprParser,
883
+ createOptionalParser(promiseCompose(createTupleParser([
884
+ javaSkippableParser,
885
+ javaComparisonOperatorParser,
886
+ javaSkippableParser,
887
+ javaRelationalExprParser,
888
+ ]), ([, operator, , right]) => ({ operator, right }))),
889
+ ]), ([left, comparison]) => {
890
+ if (comparison) {
891
+ return {
892
+ type: 'BinaryExpr',
893
+ left,
894
+ right: comparison.right,
895
+ operator: comparison.operator,
896
+ };
897
+ }
898
+ return left;
899
+ });
900
+ setParserName(javaComparisonExprParser, 'javaComparisonExprParser');
901
+ // Logical AND expression
902
+ const javaLogicalAndExprParser = promiseCompose(createTupleParser([
903
+ javaComparisonExprParser,
904
+ createArrayParser(promiseCompose(createTupleParser([
905
+ javaSkippableParser,
906
+ createExactSequenceParser('&&'),
907
+ javaSkippableParser,
908
+ javaComparisonExprParser,
909
+ ]), ([, , , right]) => right)),
910
+ ]), ([left, rights]) => {
911
+ let result = left;
912
+ for (const right of rights) {
913
+ result = {
914
+ type: 'BinaryExpr',
915
+ left: result,
916
+ right,
917
+ operator: 'AND',
918
+ };
919
+ }
920
+ return result;
921
+ });
922
+ setParserName(javaLogicalAndExprParser, 'javaLogicalAndExprParser');
923
+ // Logical OR expression
924
+ const javaLogicalOrExprParser = promiseCompose(createTupleParser([
925
+ javaLogicalAndExprParser,
926
+ createArrayParser(promiseCompose(createTupleParser([
927
+ javaSkippableParser,
928
+ createExactSequenceParser('||'),
929
+ javaSkippableParser,
930
+ javaLogicalAndExprParser,
931
+ ]), ([, , , right]) => right)),
932
+ ]), ([left, rights]) => {
933
+ let result = left;
934
+ for (const right of rights) {
935
+ result = {
936
+ type: 'BinaryExpr',
937
+ left: result,
938
+ right,
939
+ operator: 'OR',
940
+ };
941
+ }
942
+ return result;
943
+ });
944
+ setParserName(javaLogicalOrExprParser, 'javaLogicalOrExprParser');
945
+ const javaTernaryExprParser = promiseCompose(createTupleParser([
946
+ javaLogicalOrExprParser,
947
+ createOptionalParser(promiseCompose(createTupleParser([
948
+ javaSkippableParser,
949
+ createExactSequenceParser('?'),
950
+ javaSkippableParser,
951
+ (ctx) => javaTernaryExprParser(ctx), // thenExpr can be another ternary
952
+ javaSkippableParser,
953
+ createExactSequenceParser(':'),
954
+ javaSkippableParser,
955
+ (ctx) => javaTernaryExprParser(ctx), // elseExpr can be another ternary
956
+ ]), ([, , , thenExpr, , , , elseExpr]) => ({ thenExpr, elseExpr }))),
957
+ ]), ([condition, ternary]) => {
958
+ if (ternary) {
959
+ return {
960
+ type: 'ConditionalExpr',
961
+ condition,
962
+ thenExpr: ternary.thenExpr,
963
+ elseExpr: ternary.elseExpr,
964
+ };
965
+ }
966
+ return condition;
967
+ });
968
+ setParserName(javaTernaryExprParser, 'javaTernaryExprParser');
969
+ // Assignment operator
970
+ const javaAssignOperatorParser = createDisjunctionParser([
971
+ promiseCompose(createExactSequenceParser('='), () => 'ASSIGN'),
972
+ promiseCompose(createExactSequenceParser('+='), () => 'PLUS'),
973
+ promiseCompose(createExactSequenceParser('-='), () => 'MINUS'),
974
+ promiseCompose(createExactSequenceParser('*='), () => 'MULTIPLY'),
975
+ promiseCompose(createExactSequenceParser('/='), () => 'DIVIDE'),
976
+ ]);
977
+ // Expression with optional assignment
978
+ javaExpressionParser = promiseCompose(createTupleParser([
979
+ javaTernaryExprParser,
980
+ createOptionalParser(promiseCompose(createTupleParser([
981
+ javaSkippableParser,
982
+ javaAssignOperatorParser,
983
+ javaSkippableParser,
984
+ (ctx) => javaExpressionParser(ctx), // Recursive for chained assignment
985
+ ]), ([, operator, , value]) => ({ operator, value }))),
986
+ ]), ([target, assignment]) => {
987
+ if (assignment) {
988
+ return {
989
+ type: 'AssignExpr',
990
+ target,
991
+ value: assignment.value,
992
+ operator: assignment.operator,
993
+ };
994
+ }
995
+ return target;
996
+ });
997
+ setParserName(javaExpressionParser, 'javaExpressionParser');
998
+ // Skip balanced expression (fallback for complex initializers we can't parse yet)
999
+ const javaSkipInitializerParser = createObjectParser({
1000
+ _content: createRegExpParser(/[^,;{}]+/),
1001
+ type: 'UnparsedExpr',
1002
+ });
1003
+ // Expression parser with fallback
1004
+ const javaInitializerExprParser = createDisjunctionParser([
1005
+ javaExpressionParser,
1006
+ javaSkipInitializerParser,
1007
+ ]);
1008
+ const javaReturnStmtParser = promiseCompose(createTupleParser([
1009
+ createExactSequenceParser('return'),
1010
+ javaSkippableParser,
1011
+ createOptionalParser(promiseCompose(createTupleParser([
1012
+ javaExpressionParser,
1013
+ javaSkippableParser,
1014
+ ]), ([expr]) => expr)),
1015
+ createExactSequenceParser(';'),
1016
+ ]), ([, , expression]) => ({
1017
+ type: 'ReturnStmt',
1018
+ ...(expression ? { expression } : {}),
1019
+ }));
1020
+ setParserName(javaReturnStmtParser, 'javaReturnStmtParser');
1021
+ const javaThrowStmtParser = createObjectParser({
1022
+ _throw: createExactSequenceParser('throw'),
1023
+ _ws1: javaSkippableParser,
1024
+ type: 'ThrowStmt',
1025
+ expression: javaExpressionParser,
1026
+ _ws2: javaSkippableParser,
1027
+ _semi: createExactSequenceParser(';'),
1028
+ });
1029
+ setParserName(javaThrowStmtParser, 'javaThrowStmtParser');
1030
+ const javaExpressionStmtParser = createObjectParser({
1031
+ type: 'ExpressionStmt',
1032
+ expression: javaExpressionParser,
1033
+ _ws1: javaSkippableParser,
1034
+ _semi: createExactSequenceParser(';'),
1035
+ });
1036
+ setParserName(javaExpressionStmtParser, 'javaExpressionStmtParser');
1037
+ const javaIfStmtParser = promiseCompose(createTupleParser([
1038
+ createExactSequenceParser('if'),
1039
+ javaSkippableParser,
1040
+ createExactSequenceParser('('),
1041
+ javaSkippableParser,
1042
+ javaExpressionParser,
1043
+ javaSkippableParser,
1044
+ createExactSequenceParser(')'),
1045
+ javaSkippableParser,
1046
+ (ctx) => javaStatementParser(ctx),
1047
+ createOptionalParser(promiseCompose(createTupleParser([
1048
+ javaSkippableParser,
1049
+ createExactSequenceParser('else'),
1050
+ javaSkippableParser,
1051
+ (ctx) => javaStatementParser(ctx),
1052
+ ]), ([, , , elseStmt]) => elseStmt)),
1053
+ ]), ([, , , , condition, , , , thenStmt, elseStmt]) => ({
1054
+ type: 'IfStmt',
1055
+ condition,
1056
+ thenStmt,
1057
+ ...(elseStmt ? { elseStmt } : {}),
1058
+ }));
1059
+ setParserName(javaIfStmtParser, 'javaIfStmtParser');
1060
+ // Define the block statement parser with actual statements
1061
+ javaBlockStmtParserWithStatements = createObjectParser({
1062
+ _open: createExactSequenceParser('{'),
1063
+ _ws1: javaSkippableParser,
1064
+ type: 'BlockStmt',
1065
+ statements: createArrayParser(promiseCompose(createTupleParser([
1066
+ (ctx) => javaStatementParser(ctx),
1067
+ javaSkippableParser,
1068
+ ]), ([stmt]) => stmt)),
1069
+ _close: createExactSequenceParser('}'),
1070
+ });
1071
+ setParserName(javaBlockStmtParserWithStatements, 'javaBlockStmtParserWithStatements');
1072
+ const javaVariableDeclarationExprParser = promiseCompose(createTupleParser([
1073
+ javaAnnotationsParser,
1074
+ javaModifiersParser,
1075
+ javaTypeParser,
1076
+ javaSkippableParser,
1077
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
1078
+ javaSimpleNameParser,
1079
+ javaSkippableParser,
1080
+ createOptionalParser(promiseCompose(createTupleParser([
1081
+ createExactSequenceParser('='),
1082
+ javaSkippableParser,
1083
+ javaExpressionParser,
1084
+ ]), ([, , init]) => init)),
1085
+ ]), ([name, , initializer]) => ({ name, initializer })), promiseCompose(createTupleParser([
1086
+ createExactSequenceParser(','),
1087
+ javaSkippableParser,
1088
+ ]), () => ',')),
1089
+ ]), ([annotations, modifiers, type_, , variables]) => ({
1090
+ type: 'VariableDeclarationExpr',
1091
+ modifiers,
1092
+ annotations,
1093
+ variables: variables.map(v => ({
1094
+ type: 'VariableDeclarator',
1095
+ name: v.name,
1096
+ type_,
1097
+ ...(v.initializer ? { initializer: v.initializer } : {}),
1098
+ })),
1099
+ }));
1100
+ setParserName(javaVariableDeclarationExprParser, 'javaVariableDeclarationExprParser');
1101
+ const javaLocalVarDeclStmtParser = createObjectParser({
1102
+ type: 'ExpressionStmt',
1103
+ expression: javaVariableDeclarationExprParser,
1104
+ _ws1: javaSkippableParser,
1105
+ _semi: createExactSequenceParser(';'),
1106
+ });
1107
+ setParserName(javaLocalVarDeclStmtParser, 'javaLocalVarDeclStmtParser');
1108
+ const javaForStmtParser = promiseCompose(createTupleParser([
1109
+ createExactSequenceParser('for'),
1110
+ javaSkippableParser,
1111
+ createExactSequenceParser('('),
1112
+ javaSkippableParser,
1113
+ // Initialization: can be variable declaration or expression list
1114
+ createOptionalParser(createDisjunctionParser([
1115
+ javaVariableDeclarationExprParser,
1116
+ javaExpressionParser,
1117
+ ])),
1118
+ javaSkippableParser,
1119
+ createExactSequenceParser(';'),
1120
+ javaSkippableParser,
1121
+ // Condition
1122
+ createOptionalParser(javaExpressionParser),
1123
+ javaSkippableParser,
1124
+ createExactSequenceParser(';'),
1125
+ javaSkippableParser,
1126
+ // Update: expression list (comma-separated)
1127
+ createOptionalParser(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
1128
+ javaExpressionParser,
1129
+ javaSkippableParser,
1130
+ ]), ([expr]) => expr), promiseCompose(createTupleParser([
1131
+ createExactSequenceParser(','),
1132
+ javaSkippableParser,
1133
+ ]), () => ','))),
1134
+ javaSkippableParser,
1135
+ createExactSequenceParser(')'),
1136
+ javaSkippableParser,
1137
+ (ctx) => javaStatementParser(ctx),
1138
+ ]), ([, , , , init, , , , condition, , , , update, , , , body]) => ({
1139
+ type: 'ForStmt',
1140
+ initialization: init ? [init] : [],
1141
+ ...(condition ? { compare: condition } : {}),
1142
+ update: update ?? [],
1143
+ body,
1144
+ }));
1145
+ setParserName(javaForStmtParser, 'javaForStmtParser');
1146
+ const javaForEachStmtParser = createObjectParser({
1147
+ _for: createExactSequenceParser('for'),
1148
+ _ws1: javaSkippableParser,
1149
+ _open: createExactSequenceParser('('),
1150
+ _ws2: javaSkippableParser,
1151
+ type: 'ForEachStmt',
1152
+ variable: javaVariableDeclarationExprParser,
1153
+ _ws3: javaSkippableParser,
1154
+ _colon: createExactSequenceParser(':'),
1155
+ _ws4: javaSkippableParser,
1156
+ iterable: javaExpressionParser,
1157
+ _ws5: javaSkippableParser,
1158
+ _close: createExactSequenceParser(')'),
1159
+ _ws6: javaSkippableParser,
1160
+ body: (ctx) => javaStatementParser(ctx),
1161
+ });
1162
+ setParserName(javaForEachStmtParser, 'javaForEachStmtParser');
1163
+ const javaExplicitConstructorInvocationStmtParser = promiseCompose(createTupleParser([
1164
+ createDisjunctionParser([
1165
+ promiseCompose(createExactSequenceParser('this'), () => true),
1166
+ promiseCompose(createExactSequenceParser('super'), () => false),
1167
+ ]),
1168
+ javaSkippableParser,
1169
+ createExactSequenceParser('('),
1170
+ javaSkippableParser,
1171
+ createOptionalParser(createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
1172
+ javaExpressionParser,
1173
+ javaSkippableParser,
1174
+ ]), ([expr]) => expr), promiseCompose(createTupleParser([
1175
+ createExactSequenceParser(','),
1176
+ javaSkippableParser,
1177
+ ]), () => ','))),
1178
+ createExactSequenceParser(')'),
1179
+ javaSkippableParser,
1180
+ createExactSequenceParser(';'),
1181
+ ]), ([isThis, , , , args]) => ({
1182
+ type: 'ExplicitConstructorInvocationStmt',
1183
+ isThis,
1184
+ arguments: args ?? [],
1185
+ }));
1186
+ setParserName(javaExplicitConstructorInvocationStmtParser, 'javaExplicitConstructorInvocationStmtParser');
1187
+ const javaCatchClauseParser = createObjectParser({
1188
+ _catch: createExactSequenceParser('catch'),
1189
+ _ws1: javaSkippableParser,
1190
+ _open: createExactSequenceParser('('),
1191
+ _ws2: javaSkippableParser,
1192
+ type: 'CatchClause',
1193
+ parameter: javaParameterParser,
1194
+ _ws3: javaSkippableParser,
1195
+ _close: createExactSequenceParser(')'),
1196
+ _ws4: javaSkippableParser,
1197
+ body: (ctx) => javaBlockStmtParserWithStatements(ctx),
1198
+ });
1199
+ setParserName(javaCatchClauseParser, 'javaCatchClauseParser');
1200
+ const javaTryStmtParser = promiseCompose(createTupleParser([
1201
+ createExactSequenceParser('try'),
1202
+ javaSkippableParser,
1203
+ // Optional resources for try-with-resources: try (Resource r = ...)
1204
+ createOptionalParser(promiseCompose(createTupleParser([
1205
+ createExactSequenceParser('('),
1206
+ javaSkippableParser,
1207
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
1208
+ javaVariableDeclarationExprParser,
1209
+ javaSkippableParser,
1210
+ ]), ([resource]) => resource), promiseCompose(createTupleParser([
1211
+ createExactSequenceParser(';'),
1212
+ javaSkippableParser,
1213
+ ]), () => ';')),
1214
+ // Optional trailing semicolon
1215
+ createOptionalParser(createExactSequenceParser(';')),
1216
+ javaSkippableParser,
1217
+ createExactSequenceParser(')'),
1218
+ javaSkippableParser,
1219
+ ]), ([, , resources]) => resources)),
1220
+ (ctx) => javaBlockStmtParserWithStatements(ctx),
1221
+ javaSkippableParser,
1222
+ createArrayParser(promiseCompose(createTupleParser([
1223
+ javaCatchClauseParser,
1224
+ javaSkippableParser,
1225
+ ]), ([clause]) => clause)),
1226
+ createOptionalParser(promiseCompose(createTupleParser([
1227
+ createExactSequenceParser('finally'),
1228
+ javaSkippableParser,
1229
+ (ctx) => javaBlockStmtParserWithStatements(ctx),
1230
+ ]), ([, , block]) => block)),
1231
+ ]), ([, , resources, tryBlock, , catchClauses, finallyBlock]) => ({
1232
+ type: 'TryStmt',
1233
+ resources: resources ?? [],
1234
+ tryBlock,
1235
+ catchClauses,
1236
+ ...(finallyBlock ? { finallyBlock } : {}),
1237
+ }));
1238
+ setParserName(javaTryStmtParser, 'javaTryStmtParser');
1239
+ const javaSwitchEntryParser = createDisjunctionParser([
1240
+ // case expression:
1241
+ promiseCompose(createTupleParser([
1242
+ createExactSequenceParser('case'),
1243
+ javaSkippableParser,
1244
+ javaExpressionParser,
1245
+ javaSkippableParser,
1246
+ createExactSequenceParser(':'),
1247
+ javaSkippableParser,
1248
+ // Parse statements until we hit another case/default or closing brace
1249
+ createArrayParser(promiseCompose(createTupleParser([
1250
+ (ctx) => javaStatementParser(ctx),
1251
+ javaSkippableParser,
1252
+ ]), ([stmt]) => stmt)),
1253
+ ]), ([, , expr, , , , statements]) => ({
1254
+ type: 'SwitchEntry',
1255
+ isDefault: false,
1256
+ labels: [expr],
1257
+ statements,
1258
+ type_: 'STATEMENT_GROUP',
1259
+ })),
1260
+ // default:
1261
+ promiseCompose(createTupleParser([
1262
+ createExactSequenceParser('default'),
1263
+ javaSkippableParser,
1264
+ createExactSequenceParser(':'),
1265
+ javaSkippableParser,
1266
+ // Parse statements until we hit another case/default or closing brace
1267
+ createArrayParser(promiseCompose(createTupleParser([
1268
+ (ctx) => javaStatementParser(ctx),
1269
+ javaSkippableParser,
1270
+ ]), ([stmt]) => stmt)),
1271
+ ]), ([, , , , statements]) => ({
1272
+ type: 'SwitchEntry',
1273
+ isDefault: true,
1274
+ labels: [],
1275
+ statements,
1276
+ type_: 'STATEMENT_GROUP',
1277
+ })),
1278
+ ]);
1279
+ setParserName(javaSwitchEntryParser, 'javaSwitchEntryParser');
1280
+ const javaSwitchStmtParser = promiseCompose(createTupleParser([
1281
+ createExactSequenceParser('switch'),
1282
+ javaSkippableParser,
1283
+ createExactSequenceParser('('),
1284
+ javaSkippableParser,
1285
+ javaExpressionParser,
1286
+ javaSkippableParser,
1287
+ createExactSequenceParser(')'),
1288
+ javaSkippableParser,
1289
+ createExactSequenceParser('{'),
1290
+ javaSkippableParser,
1291
+ createArrayParser(promiseCompose(createTupleParser([
1292
+ javaSwitchEntryParser,
1293
+ javaSkippableParser,
1294
+ ]), ([entry]) => entry)),
1295
+ createExactSequenceParser('}'),
1296
+ ]), ([, , , , selector, , , , , , entries]) => ({
1297
+ type: 'SwitchStmt',
1298
+ selector,
1299
+ entries,
1300
+ }));
1301
+ setParserName(javaSwitchStmtParser, 'javaSwitchStmtParser');
1302
+ // Statement parser - combines all statement types
1303
+ javaStatementParser = createDisjunctionParser([
1304
+ javaReturnStmtParser,
1305
+ javaThrowStmtParser,
1306
+ javaIfStmtParser,
1307
+ javaForEachStmtParser, // Must come before ForStmt (both start with 'for')
1308
+ javaForStmtParser,
1309
+ javaTryStmtParser,
1310
+ javaSwitchStmtParser,
1311
+ javaExplicitConstructorInvocationStmtParser, // Must come before expression statement
1312
+ javaBlockStmtParserWithStatements,
1313
+ javaLocalVarDeclStmtParser, // Local variable declarations
1314
+ javaExpressionStmtParser, // Must be last since it's most general
1315
+ ]);
1316
+ setParserName(javaStatementParser, 'javaStatementParser');
1317
+ const javaFieldDeclarationParser = promiseCompose(createTupleParser([
1318
+ javaAnnotationsParser,
1319
+ javaModifiersParser,
1320
+ javaTypeParser,
1321
+ javaSkippableParser,
1322
+ createSeparatedNonEmptyArrayParser(promiseCompose(createTupleParser([
1323
+ javaSimpleNameParser,
1324
+ javaSkippableParser,
1325
+ createOptionalParser(promiseCompose(createTupleParser([
1326
+ createExactSequenceParser('='),
1327
+ javaSkippableParser,
1328
+ javaInitializerExprParser,
1329
+ ]), ([, , init]) => init)),
1330
+ ]), ([name, , initializer]) => ({ name, initializer })), promiseCompose(createTupleParser([
1331
+ createExactSequenceParser(','),
1332
+ javaSkippableParser,
1333
+ ]), () => ',')),
1334
+ javaSkippableParser,
1335
+ createExactSequenceParser(';'),
1336
+ ]), ([annotations, modifiers, type_, , variables]) => ({
1337
+ type: 'FieldDeclaration',
1338
+ modifiers,
1339
+ annotations,
1340
+ variables: variables.map(v => ({
1341
+ type: 'VariableDeclarator',
1342
+ name: v.name,
1343
+ type_,
1344
+ ...(v.initializer ? { initializer: v.initializer } : {}),
1345
+ })),
1346
+ }));
1347
+ setParserName(javaFieldDeclarationParser, 'javaFieldDeclarationParser');
1348
+ const javaConstructorDeclarationParser = promiseCompose(createTupleParser([
1349
+ javaAnnotationsParser,
1350
+ javaModifiersParser,
1351
+ // Constructor name (same as class name)
1352
+ javaSimpleNameParser,
1353
+ javaSkippableParser,
1354
+ javaParameterListParser,
1355
+ javaSkippableParser,
1356
+ createOptionalParser(promiseCompose(createTupleParser([
1357
+ javaThrowsClauseParser,
1358
+ javaSkippableParser,
1359
+ ]), ([throws]) => throws)),
1360
+ (ctx) => javaBlockStmtParserWithStatements(ctx),
1361
+ ]), ([annotations, modifiers, name, , parameters, , thrownExceptions, body]) => ({
1362
+ type: 'ConstructorDeclaration',
1363
+ modifiers,
1364
+ annotations,
1365
+ typeParameters: [],
1366
+ name,
1367
+ parameters,
1368
+ thrownExceptions: thrownExceptions ?? [],
1369
+ body,
1370
+ }));
1371
+ setParserName(javaConstructorDeclarationParser, 'javaConstructorDeclarationParser');
1372
+ // We need to try method first because field declaration also starts with modifiers + type + name
1373
+ // But constructors don't have a return type, so we try constructor after field fails
1374
+ // Note: javaBodyDeclarationParser is reassigned later to include nested type declarations
1375
+ let javaBodyDeclarationParser = createDisjunctionParser([
1376
+ javaMethodDeclarationParser,
1377
+ javaConstructorDeclarationParser,
1378
+ javaFieldDeclarationParser,
1379
+ ]);
1380
+ setParserName(javaBodyDeclarationParser, 'javaBodyDeclarationParser');
1381
+ // Class body: { member1 member2 ... }
1382
+ const javaClassBodyParser = promiseCompose(createTupleParser([
1383
+ createExactSequenceParser('{'),
1384
+ javaSkippableParser,
1385
+ createArrayParser(promiseCompose(createTupleParser([
1386
+ (ctx) => javaBodyDeclarationParser(ctx), // Use function to pick up reassigned value
1387
+ javaSkippableParser,
1388
+ ]), ([member]) => member)),
1389
+ createExactSequenceParser('}'),
1390
+ ]), ([, , members]) => members);
1391
+ const javaClassDeclarationParser = promiseCompose(createTupleParser([
1392
+ javaSkippableParser, // Skip leading comments (e.g., javadoc)
1393
+ javaAnnotationsParser,
1394
+ javaModifiersParser,
1395
+ createExactSequenceParser('class'),
1396
+ javaSkippableParser,
1397
+ javaSimpleNameParser,
1398
+ javaSkippableParser,
1399
+ createOptionalParser(promiseCompose(createTupleParser([javaTypeParametersParser, javaSkippableParser]), ([params]) => params)),
1400
+ createOptionalParser(promiseCompose(createTupleParser([javaExtendsClauseParser, javaSkippableParser]), ([types]) => types)),
1401
+ createOptionalParser(promiseCompose(createTupleParser([javaImplementsClauseParser, javaSkippableParser]), ([types]) => types)),
1402
+ // TODO: permits clause
1403
+ javaClassBodyParser,
1404
+ ]), ([, annotations, modifiers, , , name, , typeParameters, extendedTypes, implementedTypes, members]) => ({
1405
+ type: 'ClassOrInterfaceDeclaration',
1406
+ modifiers,
1407
+ annotations,
1408
+ name,
1409
+ isInterface: false,
1410
+ typeParameters: typeParameters ?? [],
1411
+ extendedTypes: extendedTypes ?? [],
1412
+ implementedTypes: implementedTypes ?? [],
1413
+ permittedTypes: [],
1414
+ members,
1415
+ }));
1416
+ setParserName(javaClassDeclarationParser, 'javaClassDeclarationParser');
1417
+ const javaInterfaceDeclarationParser = promiseCompose(createTupleParser([
1418
+ javaSkippableParser, // Skip leading comments (e.g., javadoc)
1419
+ javaAnnotationsParser,
1420
+ javaModifiersParser,
1421
+ createExactSequenceParser('interface'),
1422
+ javaSkippableParser,
1423
+ javaSimpleNameParser,
1424
+ javaSkippableParser,
1425
+ createOptionalParser(promiseCompose(createTupleParser([javaTypeParametersParser, javaSkippableParser]), ([params]) => params)),
1426
+ createOptionalParser(promiseCompose(createTupleParser([javaExtendsClauseParser, javaSkippableParser]), ([types]) => types)),
1427
+ // TODO: permits clause
1428
+ javaClassBodyParser,
1429
+ ]), ([, annotations, modifiers, , , name, , typeParameters, extendedTypes, members]) => ({
1430
+ type: 'ClassOrInterfaceDeclaration',
1431
+ modifiers,
1432
+ annotations,
1433
+ name,
1434
+ isInterface: true,
1435
+ typeParameters: typeParameters ?? [],
1436
+ extendedTypes: extendedTypes ?? [],
1437
+ implementedTypes: [],
1438
+ permittedTypes: [],
1439
+ members,
1440
+ }));
1441
+ setParserName(javaInterfaceDeclarationParser, 'javaInterfaceDeclarationParser');
1442
+ // Enum declaration
1443
+ const javaEnumDeclarationParser = promiseCompose(createTupleParser([
1444
+ javaSkippableParser, // Skip leading comments
1445
+ javaAnnotationsParser,
1446
+ javaModifiersParser,
1447
+ createExactSequenceParser('enum'),
1448
+ javaSkippableParser,
1449
+ javaSimpleNameParser,
1450
+ javaSkippableParser,
1451
+ // TODO: implements clause
1452
+ // TODO: parse enum entries and members
1453
+ javaSkipBalancedBracesParser, // Skip body for now
1454
+ ]), ([, annotations, modifiers, , , name]) => ({
1455
+ type: 'EnumDeclaration',
1456
+ modifiers,
1457
+ annotations,
1458
+ name,
1459
+ implementedTypes: [],
1460
+ entries: [],
1461
+ members: [],
1462
+ }));
1463
+ setParserName(javaEnumDeclarationParser, 'javaEnumDeclarationParser');
1464
+ // Record declaration
1465
+ const javaRecordDeclarationParser = promiseCompose(createTupleParser([
1466
+ javaAnnotationsParser,
1467
+ javaModifiersParser,
1468
+ createExactSequenceParser('record'),
1469
+ javaSkippableParser,
1470
+ javaIdentifierParser,
1471
+ javaSkippableParser,
1472
+ // TODO: type parameters
1473
+ // TODO: record components (required)
1474
+ // TODO: implements clause
1475
+ javaSkipBalancedBracesParser, // Skip body for now
1476
+ ]), ([annotations, modifiers, , , name]) => ({
1477
+ type: 'record',
1478
+ annotations,
1479
+ modifiers,
1480
+ name,
1481
+ }));
1482
+ setParserName(javaRecordDeclarationParser, 'javaRecordDeclarationParser');
1483
+ // Annotation type declaration
1484
+ const javaAnnotationDeclarationParser = promiseCompose(createTupleParser([
1485
+ javaAnnotationsParser,
1486
+ javaModifiersParser,
1487
+ createExactSequenceParser('@'),
1488
+ javaOptionalWhitespaceParser,
1489
+ createExactSequenceParser('interface'),
1490
+ javaSkippableParser,
1491
+ javaIdentifierParser,
1492
+ javaSkippableParser,
1493
+ javaSkipBalancedBracesParser, // Skip body for now
1494
+ ]), ([annotations, modifiers, , , , , name]) => ({
1495
+ type: 'annotation',
1496
+ annotations,
1497
+ modifiers,
1498
+ name,
1499
+ }));
1500
+ setParserName(javaAnnotationDeclarationParser, 'javaAnnotationDeclarationParser');
1501
+ // Type declaration (any kind)
1502
+ const javaTypeDeclarationParser = createDisjunctionParser([
1503
+ javaAnnotationDeclarationParser, // Must come before class (both start with annotations/modifiers)
1504
+ javaClassDeclarationParser,
1505
+ javaInterfaceDeclarationParser,
1506
+ javaEnumDeclarationParser,
1507
+ javaRecordDeclarationParser,
1508
+ ]);
1509
+ // Now reassign javaBodyDeclarationParser to include nested type declarations
1510
+ javaBodyDeclarationParser = createDisjunctionParser([
1511
+ javaMethodDeclarationParser,
1512
+ javaConstructorDeclarationParser,
1513
+ javaFieldDeclarationParser,
1514
+ javaClassDeclarationParser, // Nested class
1515
+ javaInterfaceDeclarationParser, // Nested interface
1516
+ javaEnumDeclarationParser, // Nested enum
1517
+ ]);
1518
+ setParserName(javaBodyDeclarationParser, 'javaBodyDeclarationParser');
1519
+ setParserName(javaTypeDeclarationParser, 'javaTypeDeclarationParser');
1520
+ // Compilation unit (top-level)
1521
+ export const javaCompilationUnitParser = createObjectParser({
1522
+ type: 'CompilationUnit',
1523
+ _ws1: javaSkippableParser,
1524
+ packageDeclaration: createOptionalParser(promiseCompose(createTupleParser([
1525
+ javaPackageDeclarationParserNew,
1526
+ javaSkippableParser,
1527
+ ]), ([pkg]) => pkg)),
1528
+ imports: createArrayParser(promiseCompose(createTupleParser([
1529
+ javaImportDeclarationParser,
1530
+ javaSkippableParser,
1531
+ ]), ([imp]) => imp)),
1532
+ types: createArrayParser(promiseCompose(createTupleParser([
1533
+ javaTypeDeclarationParser,
1534
+ javaSkippableParser,
1535
+ ]), ([type]) => type)),
1536
+ _ws2: javaSkippableParser,
1537
+ });
1538
+ setParserName(javaCompilationUnitParser, 'javaCompilationUnitParser');