driftdetect-core 0.1.2 → 0.3.0

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 (193) hide show
  1. package/dist/boundaries/boundary-store.d.ts +92 -0
  2. package/dist/boundaries/boundary-store.d.ts.map +1 -0
  3. package/dist/boundaries/boundary-store.js +458 -0
  4. package/dist/boundaries/boundary-store.js.map +1 -0
  5. package/dist/boundaries/index.d.ts +8 -0
  6. package/dist/boundaries/index.d.ts.map +1 -0
  7. package/dist/boundaries/index.js +8 -0
  8. package/dist/boundaries/index.js.map +1 -0
  9. package/dist/boundaries/types.d.ts +237 -0
  10. package/dist/boundaries/types.d.ts.map +1 -0
  11. package/dist/boundaries/types.js +8 -0
  12. package/dist/boundaries/types.js.map +1 -0
  13. package/dist/dna/ai-context.d.ts +10 -0
  14. package/dist/dna/ai-context.d.ts.map +1 -0
  15. package/dist/dna/ai-context.js +46 -0
  16. package/dist/dna/ai-context.js.map +1 -0
  17. package/dist/dna/dna-analyzer.d.ts +34 -0
  18. package/dist/dna/dna-analyzer.d.ts.map +1 -0
  19. package/dist/dna/dna-analyzer.js +110 -0
  20. package/dist/dna/dna-analyzer.js.map +1 -0
  21. package/dist/dna/dna-store.d.ts +13 -0
  22. package/dist/dna/dna-store.d.ts.map +1 -0
  23. package/dist/dna/dna-store.js +43 -0
  24. package/dist/dna/dna-store.js.map +1 -0
  25. package/dist/dna/gene-extractors/animation-approach.d.ts +15 -0
  26. package/dist/dna/gene-extractors/animation-approach.d.ts.map +1 -0
  27. package/dist/dna/gene-extractors/animation-approach.js +97 -0
  28. package/dist/dna/gene-extractors/animation-approach.js.map +1 -0
  29. package/dist/dna/gene-extractors/base-extractor.d.ts +53 -0
  30. package/dist/dna/gene-extractors/base-extractor.d.ts.map +1 -0
  31. package/dist/dna/gene-extractors/base-extractor.js +76 -0
  32. package/dist/dna/gene-extractors/base-extractor.js.map +1 -0
  33. package/dist/dna/gene-extractors/index.d.ts +16 -0
  34. package/dist/dna/gene-extractors/index.d.ts.map +1 -0
  35. package/dist/dna/gene-extractors/index.js +38 -0
  36. package/dist/dna/gene-extractors/index.js.map +1 -0
  37. package/dist/dna/gene-extractors/responsive-approach.d.ts +10 -0
  38. package/dist/dna/gene-extractors/responsive-approach.d.ts.map +1 -0
  39. package/dist/dna/gene-extractors/responsive-approach.js +30 -0
  40. package/dist/dna/gene-extractors/responsive-approach.js.map +1 -0
  41. package/dist/dna/gene-extractors/spacing-philosophy.d.ts +10 -0
  42. package/dist/dna/gene-extractors/spacing-philosophy.d.ts.map +1 -0
  43. package/dist/dna/gene-extractors/spacing-philosophy.js +30 -0
  44. package/dist/dna/gene-extractors/spacing-philosophy.js.map +1 -0
  45. package/dist/dna/gene-extractors/state-styling.d.ts +10 -0
  46. package/dist/dna/gene-extractors/state-styling.d.ts.map +1 -0
  47. package/dist/dna/gene-extractors/state-styling.js +29 -0
  48. package/dist/dna/gene-extractors/state-styling.js.map +1 -0
  49. package/dist/dna/gene-extractors/theming.d.ts +10 -0
  50. package/dist/dna/gene-extractors/theming.d.ts.map +1 -0
  51. package/dist/dna/gene-extractors/theming.js +30 -0
  52. package/dist/dna/gene-extractors/theming.js.map +1 -0
  53. package/dist/dna/gene-extractors/variant-handling.d.ts +13 -0
  54. package/dist/dna/gene-extractors/variant-handling.d.ts.map +1 -0
  55. package/dist/dna/gene-extractors/variant-handling.js +38 -0
  56. package/dist/dna/gene-extractors/variant-handling.js.map +1 -0
  57. package/dist/dna/health-calculator.d.ts +21 -0
  58. package/dist/dna/health-calculator.d.ts.map +1 -0
  59. package/dist/dna/health-calculator.js +113 -0
  60. package/dist/dna/health-calculator.js.map +1 -0
  61. package/dist/dna/index.d.ts +21 -0
  62. package/dist/dna/index.d.ts.map +1 -0
  63. package/dist/dna/index.js +19 -0
  64. package/dist/dna/index.js.map +1 -0
  65. package/dist/dna/mutation-detector.d.ts +10 -0
  66. package/dist/dna/mutation-detector.d.ts.map +1 -0
  67. package/dist/dna/mutation-detector.js +39 -0
  68. package/dist/dna/mutation-detector.js.map +1 -0
  69. package/dist/dna/playbook-generator.d.ts +6 -0
  70. package/dist/dna/playbook-generator.d.ts.map +1 -0
  71. package/dist/dna/playbook-generator.js +53 -0
  72. package/dist/dna/playbook-generator.js.map +1 -0
  73. package/dist/dna/types.d.ts +95 -0
  74. package/dist/dna/types.d.ts.map +1 -0
  75. package/dist/dna/types.js +8 -0
  76. package/dist/dna/types.js.map +1 -0
  77. package/dist/index.d.ts +7 -0
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +10 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/parsers/parser-manager.d.ts.map +1 -1
  82. package/dist/parsers/parser-manager.js +2 -0
  83. package/dist/parsers/parser-manager.js.map +1 -1
  84. package/dist/parsers/tree-sitter/config.d.ts +82 -0
  85. package/dist/parsers/tree-sitter/config.d.ts.map +1 -0
  86. package/dist/parsers/tree-sitter/config.js +200 -0
  87. package/dist/parsers/tree-sitter/config.js.map +1 -0
  88. package/dist/parsers/tree-sitter/csharp-ast-converter.d.ts +64 -0
  89. package/dist/parsers/tree-sitter/csharp-ast-converter.d.ts.map +1 -0
  90. package/dist/parsers/tree-sitter/csharp-ast-converter.js +271 -0
  91. package/dist/parsers/tree-sitter/csharp-ast-converter.js.map +1 -0
  92. package/dist/parsers/tree-sitter/csharp-loader.d.ts +43 -0
  93. package/dist/parsers/tree-sitter/csharp-loader.d.ts.map +1 -0
  94. package/dist/parsers/tree-sitter/csharp-loader.js +146 -0
  95. package/dist/parsers/tree-sitter/csharp-loader.js.map +1 -0
  96. package/dist/parsers/tree-sitter/index.d.ts +26 -0
  97. package/dist/parsers/tree-sitter/index.d.ts.map +1 -0
  98. package/dist/parsers/tree-sitter/index.js +47 -0
  99. package/dist/parsers/tree-sitter/index.js.map +1 -0
  100. package/dist/parsers/tree-sitter/java/annotation-extractor.d.ts +79 -0
  101. package/dist/parsers/tree-sitter/java/annotation-extractor.d.ts.map +1 -0
  102. package/dist/parsers/tree-sitter/java/annotation-extractor.js +540 -0
  103. package/dist/parsers/tree-sitter/java/annotation-extractor.js.map +1 -0
  104. package/dist/parsers/tree-sitter/java/class-extractor.d.ts +40 -0
  105. package/dist/parsers/tree-sitter/java/class-extractor.d.ts.map +1 -0
  106. package/dist/parsers/tree-sitter/java/class-extractor.js +770 -0
  107. package/dist/parsers/tree-sitter/java/class-extractor.js.map +1 -0
  108. package/dist/parsers/tree-sitter/java/index.d.ts +14 -0
  109. package/dist/parsers/tree-sitter/java/index.d.ts.map +1 -0
  110. package/dist/parsers/tree-sitter/java/index.js +25 -0
  111. package/dist/parsers/tree-sitter/java/index.js.map +1 -0
  112. package/dist/parsers/tree-sitter/java/method-extractor.d.ts +88 -0
  113. package/dist/parsers/tree-sitter/java/method-extractor.d.ts.map +1 -0
  114. package/dist/parsers/tree-sitter/java/method-extractor.js +551 -0
  115. package/dist/parsers/tree-sitter/java/method-extractor.js.map +1 -0
  116. package/dist/parsers/tree-sitter/java/types.d.ts +545 -0
  117. package/dist/parsers/tree-sitter/java/types.d.ts.map +1 -0
  118. package/dist/parsers/tree-sitter/java/types.js +81 -0
  119. package/dist/parsers/tree-sitter/java/types.js.map +1 -0
  120. package/dist/parsers/tree-sitter/loader.d.ts +50 -0
  121. package/dist/parsers/tree-sitter/loader.d.ts.map +1 -0
  122. package/dist/parsers/tree-sitter/loader.js +156 -0
  123. package/dist/parsers/tree-sitter/loader.js.map +1 -0
  124. package/dist/parsers/tree-sitter/pydantic/config-extractor.d.ts +78 -0
  125. package/dist/parsers/tree-sitter/pydantic/config-extractor.d.ts.map +1 -0
  126. package/dist/parsers/tree-sitter/pydantic/config-extractor.js +278 -0
  127. package/dist/parsers/tree-sitter/pydantic/config-extractor.js.map +1 -0
  128. package/dist/parsers/tree-sitter/pydantic/constraint-parser.d.ts +84 -0
  129. package/dist/parsers/tree-sitter/pydantic/constraint-parser.d.ts.map +1 -0
  130. package/dist/parsers/tree-sitter/pydantic/constraint-parser.js +321 -0
  131. package/dist/parsers/tree-sitter/pydantic/constraint-parser.js.map +1 -0
  132. package/dist/parsers/tree-sitter/pydantic/field-extractor.d.ts +74 -0
  133. package/dist/parsers/tree-sitter/pydantic/field-extractor.d.ts.map +1 -0
  134. package/dist/parsers/tree-sitter/pydantic/field-extractor.js +285 -0
  135. package/dist/parsers/tree-sitter/pydantic/field-extractor.js.map +1 -0
  136. package/dist/parsers/tree-sitter/pydantic/index.d.ts +18 -0
  137. package/dist/parsers/tree-sitter/pydantic/index.d.ts.map +1 -0
  138. package/dist/parsers/tree-sitter/pydantic/index.js +23 -0
  139. package/dist/parsers/tree-sitter/pydantic/index.js.map +1 -0
  140. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.d.ts +70 -0
  141. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.d.ts.map +1 -0
  142. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.js +251 -0
  143. package/dist/parsers/tree-sitter/pydantic/inheritance-resolver.js.map +1 -0
  144. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.d.ts +102 -0
  145. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.d.ts.map +1 -0
  146. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.js +399 -0
  147. package/dist/parsers/tree-sitter/pydantic/pydantic-extractor.js.map +1 -0
  148. package/dist/parsers/tree-sitter/pydantic/type-resolver.d.ts +89 -0
  149. package/dist/parsers/tree-sitter/pydantic/type-resolver.d.ts.map +1 -0
  150. package/dist/parsers/tree-sitter/pydantic/type-resolver.js +426 -0
  151. package/dist/parsers/tree-sitter/pydantic/type-resolver.js.map +1 -0
  152. package/dist/parsers/tree-sitter/pydantic/types.d.ts +177 -0
  153. package/dist/parsers/tree-sitter/pydantic/types.d.ts.map +1 -0
  154. package/dist/parsers/tree-sitter/pydantic/types.js +139 -0
  155. package/dist/parsers/tree-sitter/pydantic/types.js.map +1 -0
  156. package/dist/parsers/tree-sitter/pydantic/validator-extractor.d.ts +88 -0
  157. package/dist/parsers/tree-sitter/pydantic/validator-extractor.d.ts.map +1 -0
  158. package/dist/parsers/tree-sitter/pydantic/validator-extractor.js +315 -0
  159. package/dist/parsers/tree-sitter/pydantic/validator-extractor.js.map +1 -0
  160. package/dist/parsers/tree-sitter/python-ast-converter.d.ts +140 -0
  161. package/dist/parsers/tree-sitter/python-ast-converter.d.ts.map +1 -0
  162. package/dist/parsers/tree-sitter/python-ast-converter.js +360 -0
  163. package/dist/parsers/tree-sitter/python-ast-converter.js.map +1 -0
  164. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.d.ts +465 -0
  165. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.d.ts.map +1 -0
  166. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.js +1146 -0
  167. package/dist/parsers/tree-sitter/tree-sitter-csharp-parser.js.map +1 -0
  168. package/dist/parsers/tree-sitter/tree-sitter-python-parser.d.ts +86 -0
  169. package/dist/parsers/tree-sitter/tree-sitter-python-parser.d.ts.map +1 -0
  170. package/dist/parsers/tree-sitter/tree-sitter-python-parser.js +177 -0
  171. package/dist/parsers/tree-sitter/tree-sitter-python-parser.js.map +1 -0
  172. package/dist/parsers/tree-sitter/types.d.ts +399 -0
  173. package/dist/parsers/tree-sitter/types.d.ts.map +1 -0
  174. package/dist/parsers/tree-sitter/types.js +20 -0
  175. package/dist/parsers/tree-sitter/types.js.map +1 -0
  176. package/dist/parsers/types.d.ts +1 -1
  177. package/dist/parsers/types.d.ts.map +1 -1
  178. package/dist/scanner/file-walker.d.ts.map +1 -1
  179. package/dist/scanner/file-walker.js +5 -0
  180. package/dist/scanner/file-walker.js.map +1 -1
  181. package/dist/store/history-store.d.ts +85 -269
  182. package/dist/store/history-store.d.ts.map +1 -1
  183. package/dist/store/history-store.js +272 -624
  184. package/dist/store/history-store.js.map +1 -1
  185. package/dist/types/index.d.ts +1 -0
  186. package/dist/types/index.d.ts.map +1 -1
  187. package/dist/types/index.js +2 -0
  188. package/dist/types/index.js.map +1 -1
  189. package/dist/types/java-type-mapping.d.ts +79 -0
  190. package/dist/types/java-type-mapping.d.ts.map +1 -0
  191. package/dist/types/java-type-mapping.js +290 -0
  192. package/dist/types/java-type-mapping.js.map +1 -0
  193. package/package.json +8 -3
@@ -0,0 +1,770 @@
1
+ /**
2
+ * Java Class Extractor
3
+ *
4
+ * Extracts class, interface, enum, and record declarations from Java AST.
5
+ * Handles all Java type declarations with their annotations, modifiers,
6
+ * inheritance, and members.
7
+ *
8
+ * @requirements Java/Spring Boot Language Support
9
+ */
10
+ import { extractAnnotations, extractParameterAnnotations } from './annotation-extractor.js';
11
+ import { extractMethod, extractConstructor, extractField } from './method-extractor.js';
12
+ // ============================================
13
+ // Position Helpers
14
+ // ============================================
15
+ /**
16
+ * Convert tree-sitter position to drift Position.
17
+ */
18
+ function toPosition(point) {
19
+ return {
20
+ row: point.row,
21
+ column: point.column,
22
+ };
23
+ }
24
+ // ============================================
25
+ // Modifier Extraction
26
+ // ============================================
27
+ /**
28
+ * Extract modifiers from a node.
29
+ */
30
+ export function extractModifiers(node) {
31
+ const modifiers = [];
32
+ // Look for modifiers node
33
+ const modifiersNode = findChildByType(node, 'modifiers');
34
+ if (modifiersNode) {
35
+ for (const child of modifiersNode.children) {
36
+ const modifier = parseModifier(child);
37
+ if (modifier) {
38
+ modifiers.push(modifier);
39
+ }
40
+ }
41
+ }
42
+ // Also check direct children for modifier keywords
43
+ for (const child of node.children) {
44
+ const modifier = parseModifier(child);
45
+ if (modifier && !modifiers.includes(modifier)) {
46
+ modifiers.push(modifier);
47
+ }
48
+ }
49
+ return modifiers;
50
+ }
51
+ /**
52
+ * Parse a single modifier from a node.
53
+ */
54
+ function parseModifier(node) {
55
+ const modifierKeywords = [
56
+ 'public', 'private', 'protected',
57
+ 'static', 'final', 'abstract',
58
+ 'synchronized', 'volatile', 'transient',
59
+ 'native', 'strictfp', 'default',
60
+ 'sealed', 'non-sealed',
61
+ ];
62
+ const text = node.text.toLowerCase();
63
+ // Handle non-sealed which might be parsed differently
64
+ if (text === 'non-sealed' || node.type === 'non_sealed') {
65
+ return 'non-sealed';
66
+ }
67
+ if (modifierKeywords.includes(text)) {
68
+ return text;
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Derive accessibility from modifiers.
74
+ */
75
+ export function deriveAccessibility(modifiers) {
76
+ if (modifiers.includes('public'))
77
+ return 'public';
78
+ if (modifiers.includes('private'))
79
+ return 'private';
80
+ if (modifiers.includes('protected'))
81
+ return 'protected';
82
+ return 'package-private';
83
+ }
84
+ // ============================================
85
+ // Class Extraction
86
+ // ============================================
87
+ /**
88
+ * Extract all class declarations from the AST.
89
+ */
90
+ export function extractClasses(root, packageName, imports) {
91
+ const classes = [];
92
+ findNodesOfType(root, 'class_declaration', (node) => {
93
+ const classInfo = parseClassDeclaration(node, packageName, imports);
94
+ if (classInfo) {
95
+ classes.push(classInfo);
96
+ }
97
+ });
98
+ return classes;
99
+ }
100
+ /**
101
+ * Parse a class declaration node.
102
+ */
103
+ function parseClassDeclaration(node, packageName, imports) {
104
+ const modifiers = extractModifiers(node);
105
+ const annotations = extractAnnotations(node, 'class', imports);
106
+ // Get class name
107
+ const nameNode = findChildByType(node, 'identifier');
108
+ if (!nameNode) {
109
+ return null;
110
+ }
111
+ const name = nameNode.text;
112
+ // Get type parameters
113
+ const typeParams = extractTypeParameters(node);
114
+ // Get superclass and interfaces
115
+ const { superclass, interfaces } = extractInheritance(node);
116
+ // Get permitted subclasses (for sealed classes)
117
+ const permittedSubclasses = extractPermittedSubclasses(node);
118
+ // Get class body
119
+ const bodyNode = findChildByType(node, 'class_body');
120
+ const { fields, methods, constructors, innerClasses } = bodyNode
121
+ ? extractClassMembers(bodyNode, imports)
122
+ : { fields: [], methods: [], constructors: [], innerClasses: [] };
123
+ return {
124
+ name,
125
+ packageName,
126
+ annotations,
127
+ modifiers,
128
+ superclass,
129
+ interfaces,
130
+ typeParameters: typeParams,
131
+ permittedSubclasses,
132
+ fields,
133
+ methods,
134
+ constructors,
135
+ innerClasses,
136
+ accessibility: deriveAccessibility(modifiers),
137
+ isAbstract: modifiers.includes('abstract'),
138
+ isFinal: modifiers.includes('final'),
139
+ isStatic: modifiers.includes('static'),
140
+ isSealed: modifiers.includes('sealed'),
141
+ isNonSealed: modifiers.includes('non-sealed'),
142
+ startPosition: toPosition(node.startPosition),
143
+ endPosition: toPosition(node.endPosition),
144
+ };
145
+ }
146
+ /**
147
+ * Extract class members from a class body.
148
+ */
149
+ function extractClassMembers(bodyNode, imports) {
150
+ const fields = [];
151
+ const methods = [];
152
+ const constructors = [];
153
+ const innerClasses = [];
154
+ for (const child of bodyNode.children) {
155
+ switch (child.type) {
156
+ case 'field_declaration':
157
+ const extractedFields = extractField(child, imports);
158
+ fields.push(...extractedFields);
159
+ break;
160
+ case 'method_declaration':
161
+ const method = extractMethod(child, imports);
162
+ if (method) {
163
+ methods.push(method);
164
+ }
165
+ break;
166
+ case 'constructor_declaration':
167
+ const constructor = extractConstructor(child, imports);
168
+ if (constructor) {
169
+ constructors.push(constructor);
170
+ }
171
+ break;
172
+ case 'class_declaration':
173
+ case 'interface_declaration':
174
+ case 'enum_declaration':
175
+ case 'record_declaration':
176
+ const innerName = findChildByType(child, 'identifier')?.text;
177
+ if (innerName) {
178
+ innerClasses.push(innerName);
179
+ }
180
+ break;
181
+ }
182
+ }
183
+ return { fields, methods, constructors, innerClasses };
184
+ }
185
+ // ============================================
186
+ // Interface Extraction
187
+ // ============================================
188
+ /**
189
+ * Extract all interface declarations from the AST.
190
+ */
191
+ export function extractInterfaces(root, packageName, imports) {
192
+ const interfaces = [];
193
+ findNodesOfType(root, 'interface_declaration', (node) => {
194
+ const interfaceInfo = parseInterfaceDeclaration(node, packageName, imports);
195
+ if (interfaceInfo) {
196
+ interfaces.push(interfaceInfo);
197
+ }
198
+ });
199
+ return interfaces;
200
+ }
201
+ /**
202
+ * Parse an interface declaration node.
203
+ */
204
+ function parseInterfaceDeclaration(node, packageName, imports) {
205
+ const modifiers = extractModifiers(node);
206
+ const annotations = extractAnnotations(node, 'interface', imports);
207
+ // Get interface name
208
+ const nameNode = findChildByType(node, 'identifier');
209
+ if (!nameNode) {
210
+ return null;
211
+ }
212
+ const name = nameNode.text;
213
+ // Get type parameters
214
+ const typeParams = extractTypeParameters(node);
215
+ // Get extended interfaces
216
+ const extendsInterfaces = extractExtendsInterfaces(node);
217
+ // Get permitted subclasses (for sealed interfaces)
218
+ const permittedSubclasses = extractPermittedSubclasses(node);
219
+ // Get interface body
220
+ const bodyNode = findChildByType(node, 'interface_body');
221
+ const { methods, fields } = bodyNode
222
+ ? extractInterfaceMembers(bodyNode, imports)
223
+ : { methods: [], fields: [] };
224
+ return {
225
+ name,
226
+ packageName,
227
+ annotations,
228
+ modifiers,
229
+ extendsInterfaces,
230
+ typeParameters: typeParams,
231
+ permittedSubclasses,
232
+ methods,
233
+ fields,
234
+ accessibility: deriveAccessibility(modifiers),
235
+ isSealed: modifiers.includes('sealed'),
236
+ isNonSealed: modifiers.includes('non-sealed'),
237
+ startPosition: toPosition(node.startPosition),
238
+ endPosition: toPosition(node.endPosition),
239
+ };
240
+ }
241
+ /**
242
+ * Extract interface members from an interface body.
243
+ */
244
+ function extractInterfaceMembers(bodyNode, imports) {
245
+ const methods = [];
246
+ const fields = [];
247
+ for (const child of bodyNode.children) {
248
+ switch (child.type) {
249
+ case 'method_declaration':
250
+ const method = extractMethod(child, imports);
251
+ if (method) {
252
+ methods.push(method);
253
+ }
254
+ break;
255
+ case 'constant_declaration':
256
+ case 'field_declaration':
257
+ const extractedFields = extractField(child, imports);
258
+ fields.push(...extractedFields);
259
+ break;
260
+ }
261
+ }
262
+ return { methods, fields };
263
+ }
264
+ // ============================================
265
+ // Enum Extraction
266
+ // ============================================
267
+ /**
268
+ * Extract all enum declarations from the AST.
269
+ */
270
+ export function extractEnums(root, packageName, imports) {
271
+ const enums = [];
272
+ findNodesOfType(root, 'enum_declaration', (node) => {
273
+ const enumInfo = parseEnumDeclaration(node, packageName, imports);
274
+ if (enumInfo) {
275
+ enums.push(enumInfo);
276
+ }
277
+ });
278
+ return enums;
279
+ }
280
+ /**
281
+ * Parse an enum declaration node.
282
+ */
283
+ function parseEnumDeclaration(node, packageName, imports) {
284
+ const modifiers = extractModifiers(node);
285
+ const annotations = extractAnnotations(node, 'enum', imports);
286
+ // Get enum name
287
+ const nameNode = findChildByType(node, 'identifier');
288
+ if (!nameNode) {
289
+ return null;
290
+ }
291
+ const name = nameNode.text;
292
+ // Get implemented interfaces
293
+ const interfaces = extractImplementsInterfaces(node);
294
+ // Get enum body
295
+ const bodyNode = findChildByType(node, 'enum_body');
296
+ const { constants, fields, methods, constructors } = bodyNode
297
+ ? extractEnumMembers(bodyNode, imports)
298
+ : { constants: [], fields: [], methods: [], constructors: [] };
299
+ return {
300
+ name,
301
+ packageName,
302
+ annotations,
303
+ modifiers,
304
+ interfaces,
305
+ constants,
306
+ fields,
307
+ methods,
308
+ constructors,
309
+ accessibility: deriveAccessibility(modifiers),
310
+ startPosition: toPosition(node.startPosition),
311
+ endPosition: toPosition(node.endPosition),
312
+ };
313
+ }
314
+ /**
315
+ * Extract enum members from an enum body.
316
+ */
317
+ function extractEnumMembers(bodyNode, imports) {
318
+ const constants = [];
319
+ const fields = [];
320
+ const methods = [];
321
+ const constructors = [];
322
+ for (const child of bodyNode.children) {
323
+ switch (child.type) {
324
+ case 'enum_constant':
325
+ const constant = parseEnumConstant(child, imports);
326
+ if (constant) {
327
+ constants.push(constant);
328
+ }
329
+ break;
330
+ case 'enum_body_declarations':
331
+ // This contains the regular class members after the constants
332
+ for (const memberChild of child.children) {
333
+ switch (memberChild.type) {
334
+ case 'field_declaration':
335
+ const extractedFields = extractField(memberChild, imports);
336
+ fields.push(...extractedFields);
337
+ break;
338
+ case 'method_declaration':
339
+ const method = extractMethod(memberChild, imports);
340
+ if (method) {
341
+ methods.push(method);
342
+ }
343
+ break;
344
+ case 'constructor_declaration':
345
+ const constructor = extractConstructor(memberChild, imports);
346
+ if (constructor) {
347
+ constructors.push(constructor);
348
+ }
349
+ break;
350
+ }
351
+ }
352
+ break;
353
+ }
354
+ }
355
+ return { constants, fields, methods, constructors };
356
+ }
357
+ /**
358
+ * Parse an enum constant.
359
+ */
360
+ function parseEnumConstant(node, imports) {
361
+ const annotations = extractAnnotations(node, 'field', imports);
362
+ // Get constant name
363
+ const nameNode = findChildByType(node, 'identifier');
364
+ if (!nameNode) {
365
+ return null;
366
+ }
367
+ const name = nameNode.text;
368
+ // Get constructor arguments
369
+ const args = [];
370
+ const argListNode = findChildByType(node, 'argument_list');
371
+ if (argListNode) {
372
+ for (const child of argListNode.children) {
373
+ if (child.type !== '(' && child.type !== ')' && child.type !== ',') {
374
+ args.push(child.text);
375
+ }
376
+ }
377
+ }
378
+ return {
379
+ name,
380
+ annotations,
381
+ arguments: args,
382
+ startPosition: toPosition(node.startPosition),
383
+ endPosition: toPosition(node.endPosition),
384
+ };
385
+ }
386
+ // ============================================
387
+ // Record Extraction (Java 16+)
388
+ // ============================================
389
+ /**
390
+ * Extract all record declarations from the AST.
391
+ */
392
+ export function extractRecords(root, packageName, imports) {
393
+ const records = [];
394
+ findNodesOfType(root, 'record_declaration', (node) => {
395
+ const recordInfo = parseRecordDeclaration(node, packageName, imports);
396
+ if (recordInfo) {
397
+ records.push(recordInfo);
398
+ }
399
+ });
400
+ return records;
401
+ }
402
+ /**
403
+ * Parse a record declaration node.
404
+ */
405
+ function parseRecordDeclaration(node, packageName, imports) {
406
+ const modifiers = extractModifiers(node);
407
+ const annotations = extractAnnotations(node, 'record', imports);
408
+ // Get record name
409
+ const nameNode = findChildByType(node, 'identifier');
410
+ if (!nameNode) {
411
+ return null;
412
+ }
413
+ const name = nameNode.text;
414
+ // Get type parameters
415
+ const typeParams = extractTypeParameters(node);
416
+ // Get record components (the parameters in the record header)
417
+ const components = extractRecordComponents(node, imports);
418
+ // Get implemented interfaces
419
+ const interfaces = extractImplementsInterfaces(node);
420
+ // Get record body
421
+ const bodyNode = findChildByType(node, 'record_body') || findChildByType(node, 'class_body');
422
+ const { methods, constructors } = bodyNode
423
+ ? extractRecordMembers(bodyNode, imports)
424
+ : { methods: [], constructors: [] };
425
+ return {
426
+ name,
427
+ packageName,
428
+ annotations,
429
+ modifiers,
430
+ components,
431
+ interfaces,
432
+ typeParameters: typeParams,
433
+ methods,
434
+ constructors,
435
+ accessibility: deriveAccessibility(modifiers),
436
+ startPosition: toPosition(node.startPosition),
437
+ endPosition: toPosition(node.endPosition),
438
+ };
439
+ }
440
+ /**
441
+ * Extract record components from the record header.
442
+ */
443
+ function extractRecordComponents(node, imports) {
444
+ const components = [];
445
+ // Find the formal parameters node (record components)
446
+ const paramsNode = findChildByType(node, 'formal_parameters') ||
447
+ findChildByType(node, 'record_component_list');
448
+ if (!paramsNode) {
449
+ return components;
450
+ }
451
+ for (const child of paramsNode.children) {
452
+ if (child.type === 'formal_parameter' || child.type === 'record_component') {
453
+ const component = parseRecordComponent(child, imports);
454
+ if (component) {
455
+ components.push(component);
456
+ }
457
+ }
458
+ }
459
+ return components;
460
+ }
461
+ /**
462
+ * Parse a single record component.
463
+ */
464
+ function parseRecordComponent(node, imports) {
465
+ const annotations = extractParameterAnnotations(node, imports);
466
+ let type = '';
467
+ let name = '';
468
+ for (const child of node.children) {
469
+ if (child.type === 'identifier') {
470
+ name = child.text;
471
+ }
472
+ else if (isTypeNode(child)) {
473
+ type = child.text;
474
+ }
475
+ }
476
+ if (!name || !type) {
477
+ return null;
478
+ }
479
+ return {
480
+ name,
481
+ type,
482
+ annotations,
483
+ };
484
+ }
485
+ /**
486
+ * Extract record members from a record body.
487
+ */
488
+ function extractRecordMembers(bodyNode, imports) {
489
+ const methods = [];
490
+ const constructors = [];
491
+ for (const child of bodyNode.children) {
492
+ switch (child.type) {
493
+ case 'method_declaration':
494
+ const method = extractMethod(child, imports);
495
+ if (method) {
496
+ methods.push(method);
497
+ }
498
+ break;
499
+ case 'constructor_declaration':
500
+ case 'compact_constructor_declaration':
501
+ const constructor = extractConstructor(child, imports);
502
+ if (constructor) {
503
+ constructors.push(constructor);
504
+ }
505
+ break;
506
+ }
507
+ }
508
+ return { methods, constructors };
509
+ }
510
+ // ============================================
511
+ // Annotation Definition Extraction
512
+ // ============================================
513
+ /**
514
+ * Extract all annotation type definitions from the AST.
515
+ */
516
+ export function extractAnnotationDefinitions(root, packageName, imports) {
517
+ const definitions = [];
518
+ findNodesOfType(root, 'annotation_type_declaration', (node) => {
519
+ const definition = parseAnnotationDefinition(node, packageName, imports);
520
+ if (definition) {
521
+ definitions.push(definition);
522
+ }
523
+ });
524
+ return definitions;
525
+ }
526
+ /**
527
+ * Parse an annotation type definition.
528
+ */
529
+ function parseAnnotationDefinition(node, packageName, imports) {
530
+ const modifiers = extractModifiers(node);
531
+ const annotations = extractAnnotations(node, 'annotation_type', imports);
532
+ // Get annotation name
533
+ const nameNode = findChildByType(node, 'identifier');
534
+ if (!nameNode) {
535
+ return null;
536
+ }
537
+ const name = nameNode.text;
538
+ // Get annotation elements
539
+ const bodyNode = findChildByType(node, 'annotation_type_body');
540
+ const elements = bodyNode
541
+ ? extractAnnotationElements(bodyNode)
542
+ : [];
543
+ return {
544
+ name,
545
+ packageName,
546
+ annotations,
547
+ elements,
548
+ accessibility: deriveAccessibility(modifiers),
549
+ startPosition: toPosition(node.startPosition),
550
+ endPosition: toPosition(node.endPosition),
551
+ };
552
+ }
553
+ /**
554
+ * Extract annotation elements from an annotation type body.
555
+ */
556
+ function extractAnnotationElements(bodyNode) {
557
+ const elements = [];
558
+ for (const child of bodyNode.children) {
559
+ if (child.type === 'annotation_type_element_declaration') {
560
+ const element = parseAnnotationElement(child);
561
+ if (element) {
562
+ elements.push(element);
563
+ }
564
+ }
565
+ }
566
+ return elements;
567
+ }
568
+ /**
569
+ * Parse a single annotation element.
570
+ */
571
+ function parseAnnotationElement(node) {
572
+ let type = '';
573
+ let name = '';
574
+ let defaultValue = null;
575
+ for (const child of node.children) {
576
+ if (child.type === 'identifier') {
577
+ name = child.text;
578
+ }
579
+ else if (isTypeNode(child)) {
580
+ type = child.text;
581
+ }
582
+ else if (child.type === 'default_value') {
583
+ // Get the value after 'default' keyword
584
+ for (const valueChild of child.children) {
585
+ if (valueChild.type !== 'default') {
586
+ defaultValue = valueChild.text;
587
+ break;
588
+ }
589
+ }
590
+ }
591
+ }
592
+ if (!name || !type) {
593
+ return null;
594
+ }
595
+ return {
596
+ name,
597
+ type,
598
+ defaultValue,
599
+ };
600
+ }
601
+ // ============================================
602
+ // Inheritance Extraction
603
+ // ============================================
604
+ /**
605
+ * Extract superclass and implemented interfaces from a class.
606
+ */
607
+ function extractInheritance(node) {
608
+ let superclass = null;
609
+ const interfaces = [];
610
+ // Look for superclass
611
+ const superclassNode = findChildByType(node, 'superclass');
612
+ if (superclassNode) {
613
+ const typeNode = findTypeInNode(superclassNode);
614
+ if (typeNode) {
615
+ superclass = typeNode.text;
616
+ }
617
+ }
618
+ // Look for interfaces
619
+ const interfacesNode = findChildByType(node, 'super_interfaces') ||
620
+ findChildByType(node, 'interfaces');
621
+ if (interfacesNode) {
622
+ const typeList = findChildByType(interfacesNode, 'type_list') ||
623
+ findChildByType(interfacesNode, 'interface_type_list');
624
+ if (typeList) {
625
+ for (const child of typeList.children) {
626
+ if (isTypeNode(child)) {
627
+ interfaces.push(child.text);
628
+ }
629
+ }
630
+ }
631
+ else {
632
+ // Direct type children
633
+ for (const child of interfacesNode.children) {
634
+ if (isTypeNode(child)) {
635
+ interfaces.push(child.text);
636
+ }
637
+ }
638
+ }
639
+ }
640
+ return { superclass, interfaces };
641
+ }
642
+ /**
643
+ * Extract extended interfaces from an interface declaration.
644
+ */
645
+ function extractExtendsInterfaces(node) {
646
+ const interfaces = [];
647
+ const extendsNode = findChildByType(node, 'extends_interfaces');
648
+ if (extendsNode) {
649
+ const typeList = findChildByType(extendsNode, 'type_list') ||
650
+ findChildByType(extendsNode, 'interface_type_list');
651
+ if (typeList) {
652
+ for (const child of typeList.children) {
653
+ if (isTypeNode(child)) {
654
+ interfaces.push(child.text);
655
+ }
656
+ }
657
+ }
658
+ else {
659
+ for (const child of extendsNode.children) {
660
+ if (isTypeNode(child)) {
661
+ interfaces.push(child.text);
662
+ }
663
+ }
664
+ }
665
+ }
666
+ return interfaces;
667
+ }
668
+ /**
669
+ * Extract implemented interfaces from a class/enum/record.
670
+ */
671
+ function extractImplementsInterfaces(node) {
672
+ const interfaces = [];
673
+ const implementsNode = findChildByType(node, 'super_interfaces') ||
674
+ findChildByType(node, 'interfaces');
675
+ if (implementsNode) {
676
+ for (const child of implementsNode.children) {
677
+ if (isTypeNode(child)) {
678
+ interfaces.push(child.text);
679
+ }
680
+ }
681
+ }
682
+ return interfaces;
683
+ }
684
+ /**
685
+ * Extract permitted subclasses for sealed types.
686
+ */
687
+ function extractPermittedSubclasses(node) {
688
+ const permitted = [];
689
+ const permitsNode = findChildByType(node, 'permits');
690
+ if (permitsNode) {
691
+ for (const child of permitsNode.children) {
692
+ if (isTypeNode(child)) {
693
+ permitted.push(child.text);
694
+ }
695
+ }
696
+ }
697
+ return permitted;
698
+ }
699
+ /**
700
+ * Extract type parameters from a generic declaration.
701
+ */
702
+ function extractTypeParameters(node) {
703
+ const params = [];
704
+ const typeParamsNode = findChildByType(node, 'type_parameters');
705
+ if (typeParamsNode) {
706
+ for (const child of typeParamsNode.children) {
707
+ if (child.type === 'type_parameter') {
708
+ const nameNode = findChildByType(child, 'identifier');
709
+ if (nameNode) {
710
+ params.push(nameNode.text);
711
+ }
712
+ }
713
+ }
714
+ }
715
+ return params;
716
+ }
717
+ // ============================================
718
+ // Utility Functions
719
+ // ============================================
720
+ /**
721
+ * Find a child node by type.
722
+ */
723
+ function findChildByType(node, type) {
724
+ for (const child of node.children) {
725
+ if (child.type === type) {
726
+ return child;
727
+ }
728
+ }
729
+ return null;
730
+ }
731
+ /**
732
+ * Find all nodes of a specific type in the tree.
733
+ */
734
+ function findNodesOfType(node, type, callback) {
735
+ if (node.type === type) {
736
+ callback(node);
737
+ }
738
+ for (const child of node.children) {
739
+ findNodesOfType(child, type, callback);
740
+ }
741
+ }
742
+ /**
743
+ * Check if a node is a type node.
744
+ */
745
+ function isTypeNode(node) {
746
+ const typeNodeTypes = [
747
+ 'type_identifier',
748
+ 'generic_type',
749
+ 'scoped_type_identifier',
750
+ 'array_type',
751
+ 'integral_type',
752
+ 'floating_point_type',
753
+ 'boolean_type',
754
+ 'void_type',
755
+ 'identifier',
756
+ ];
757
+ return typeNodeTypes.includes(node.type);
758
+ }
759
+ /**
760
+ * Find a type node within a parent node.
761
+ */
762
+ function findTypeInNode(node) {
763
+ for (const child of node.children) {
764
+ if (isTypeNode(child)) {
765
+ return child;
766
+ }
767
+ }
768
+ return null;
769
+ }
770
+ //# sourceMappingURL=class-extractor.js.map