@optave/codegraph 3.11.2 → 3.13.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 (236) hide show
  1. package/README.md +73 -37
  2. package/dist/cli/commands/audit.d.ts.map +1 -1
  3. package/dist/cli/commands/audit.js +2 -1
  4. package/dist/cli/commands/audit.js.map +1 -1
  5. package/dist/cli/commands/batch.d.ts.map +1 -1
  6. package/dist/cli/commands/batch.js +1 -0
  7. package/dist/cli/commands/batch.js.map +1 -1
  8. package/dist/cli/commands/build.d.ts.map +1 -1
  9. package/dist/cli/commands/build.js +6 -1
  10. package/dist/cli/commands/build.js.map +1 -1
  11. package/dist/cli/commands/config.d.ts +3 -0
  12. package/dist/cli/commands/config.d.ts.map +1 -0
  13. package/dist/cli/commands/config.js +272 -0
  14. package/dist/cli/commands/config.js.map +1 -0
  15. package/dist/cli/commands/triage.js +1 -1
  16. package/dist/cli/commands/triage.js.map +1 -1
  17. package/dist/cli/index.d.ts.map +1 -1
  18. package/dist/cli/index.js +10 -0
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/cli/shared/options.d.ts +2 -1
  21. package/dist/cli/shared/options.d.ts.map +1 -1
  22. package/dist/cli/shared/options.js +11 -1
  23. package/dist/cli/shared/options.js.map +1 -1
  24. package/dist/cli/types.d.ts +2 -0
  25. package/dist/cli/types.d.ts.map +1 -1
  26. package/dist/db/migrations.d.ts.map +1 -1
  27. package/dist/db/migrations.js +8 -1
  28. package/dist/db/migrations.js.map +1 -1
  29. package/dist/domain/analysis/module-map.d.ts +2 -0
  30. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  31. package/dist/domain/analysis/module-map.js +24 -2
  32. package/dist/domain/analysis/module-map.js.map +1 -1
  33. package/dist/domain/graph/builder/call-resolver.d.ts +16 -10
  34. package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
  35. package/dist/domain/graph/builder/call-resolver.js +251 -34
  36. package/dist/domain/graph/builder/call-resolver.js.map +1 -1
  37. package/dist/domain/graph/builder/cha.d.ts +69 -0
  38. package/dist/domain/graph/builder/cha.d.ts.map +1 -0
  39. package/dist/domain/graph/builder/cha.js +158 -0
  40. package/dist/domain/graph/builder/cha.js.map +1 -0
  41. package/dist/domain/graph/builder/context.d.ts +3 -0
  42. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  43. package/dist/domain/graph/builder/context.js +2 -0
  44. package/dist/domain/graph/builder/context.js.map +1 -1
  45. package/dist/domain/graph/builder/helpers.d.ts +25 -1
  46. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  47. package/dist/domain/graph/builder/helpers.js +178 -5
  48. package/dist/domain/graph/builder/helpers.js.map +1 -1
  49. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  50. package/dist/domain/graph/builder/incremental.js +74 -2
  51. package/dist/domain/graph/builder/incremental.js.map +1 -1
  52. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  53. package/dist/domain/graph/builder/pipeline.js +37 -2
  54. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  55. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  56. package/dist/domain/graph/builder/stages/build-edges.js +704 -34
  57. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  58. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  59. package/dist/domain/graph/builder/stages/detect-changes.js +3 -2
  60. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  61. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  62. package/dist/domain/graph/builder/stages/finalize.js +4 -0
  63. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  64. package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
  65. package/dist/domain/graph/builder/stages/native-orchestrator.js +783 -37
  66. package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
  67. package/dist/domain/graph/builder/stages/resolve-imports.d.ts +1 -0
  68. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  69. package/dist/domain/graph/builder/stages/resolve-imports.js +10 -1
  70. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  71. package/dist/domain/graph/journal.js +1 -1
  72. package/dist/domain/graph/journal.js.map +1 -1
  73. package/dist/domain/graph/resolver/points-to.d.ts +53 -0
  74. package/dist/domain/graph/resolver/points-to.d.ts.map +1 -0
  75. package/dist/domain/graph/resolver/points-to.js +213 -0
  76. package/dist/domain/graph/resolver/points-to.js.map +1 -0
  77. package/dist/domain/graph/resolver/ts-resolver.d.ts +9 -0
  78. package/dist/domain/graph/resolver/ts-resolver.d.ts.map +1 -0
  79. package/dist/domain/graph/resolver/ts-resolver.js +476 -0
  80. package/dist/domain/graph/resolver/ts-resolver.js.map +1 -0
  81. package/dist/domain/parser.d.ts +12 -4
  82. package/dist/domain/parser.d.ts.map +1 -1
  83. package/dist/domain/parser.js +83 -20
  84. package/dist/domain/parser.js.map +1 -1
  85. package/dist/domain/wasm-worker-entry.js +35 -2
  86. package/dist/domain/wasm-worker-entry.js.map +1 -1
  87. package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
  88. package/dist/domain/wasm-worker-pool.js +34 -0
  89. package/dist/domain/wasm-worker-pool.js.map +1 -1
  90. package/dist/domain/wasm-worker-protocol.d.ts +15 -1
  91. package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
  92. package/dist/extractors/c.js +3 -3
  93. package/dist/extractors/c.js.map +1 -1
  94. package/dist/extractors/clojure.js +1 -1
  95. package/dist/extractors/clojure.js.map +1 -1
  96. package/dist/extractors/cpp.d.ts.map +1 -1
  97. package/dist/extractors/cpp.js +45 -4
  98. package/dist/extractors/cpp.js.map +1 -1
  99. package/dist/extractors/csharp.d.ts.map +1 -1
  100. package/dist/extractors/csharp.js +37 -8
  101. package/dist/extractors/csharp.js.map +1 -1
  102. package/dist/extractors/cuda.d.ts.map +1 -1
  103. package/dist/extractors/cuda.js +45 -4
  104. package/dist/extractors/cuda.js.map +1 -1
  105. package/dist/extractors/elixir.js +6 -6
  106. package/dist/extractors/elixir.js.map +1 -1
  107. package/dist/extractors/fsharp.js +1 -1
  108. package/dist/extractors/fsharp.js.map +1 -1
  109. package/dist/extractors/go.js +5 -5
  110. package/dist/extractors/go.js.map +1 -1
  111. package/dist/extractors/haskell.js +1 -1
  112. package/dist/extractors/haskell.js.map +1 -1
  113. package/dist/extractors/helpers.d.ts +11 -0
  114. package/dist/extractors/helpers.d.ts.map +1 -1
  115. package/dist/extractors/helpers.js +40 -0
  116. package/dist/extractors/helpers.js.map +1 -1
  117. package/dist/extractors/java.d.ts.map +1 -1
  118. package/dist/extractors/java.js +10 -9
  119. package/dist/extractors/java.js.map +1 -1
  120. package/dist/extractors/javascript.d.ts +2 -0
  121. package/dist/extractors/javascript.d.ts.map +1 -1
  122. package/dist/extractors/javascript.js +1812 -71
  123. package/dist/extractors/javascript.js.map +1 -1
  124. package/dist/extractors/kotlin.js +5 -5
  125. package/dist/extractors/kotlin.js.map +1 -1
  126. package/dist/extractors/lua.js +1 -1
  127. package/dist/extractors/lua.js.map +1 -1
  128. package/dist/extractors/objc.js +3 -3
  129. package/dist/extractors/objc.js.map +1 -1
  130. package/dist/extractors/ocaml.js +1 -1
  131. package/dist/extractors/ocaml.js.map +1 -1
  132. package/dist/extractors/php.js +2 -2
  133. package/dist/extractors/php.js.map +1 -1
  134. package/dist/extractors/python.js +7 -7
  135. package/dist/extractors/python.js.map +1 -1
  136. package/dist/extractors/ruby.js +2 -2
  137. package/dist/extractors/ruby.js.map +1 -1
  138. package/dist/extractors/scala.js +1 -1
  139. package/dist/extractors/scala.js.map +1 -1
  140. package/dist/extractors/solidity.js +1 -1
  141. package/dist/extractors/solidity.js.map +1 -1
  142. package/dist/extractors/swift.js +4 -4
  143. package/dist/extractors/swift.js.map +1 -1
  144. package/dist/extractors/zig.js +4 -4
  145. package/dist/extractors/zig.js.map +1 -1
  146. package/dist/features/structure-query.d.ts +1 -1
  147. package/dist/features/structure-query.d.ts.map +1 -1
  148. package/dist/features/structure-query.js +6 -6
  149. package/dist/features/structure-query.js.map +1 -1
  150. package/dist/index.d.ts +1 -1
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +1 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/infrastructure/config.d.ts +85 -2
  155. package/dist/infrastructure/config.d.ts.map +1 -1
  156. package/dist/infrastructure/config.js +408 -19
  157. package/dist/infrastructure/config.js.map +1 -1
  158. package/dist/infrastructure/native.d.ts +11 -0
  159. package/dist/infrastructure/native.d.ts.map +1 -1
  160. package/dist/infrastructure/native.js +78 -5
  161. package/dist/infrastructure/native.js.map +1 -1
  162. package/dist/infrastructure/registry.d.ts +27 -0
  163. package/dist/infrastructure/registry.d.ts.map +1 -1
  164. package/dist/infrastructure/registry.js +59 -1
  165. package/dist/infrastructure/registry.js.map +1 -1
  166. package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
  167. package/dist/presentation/queries-cli/overview.js +5 -0
  168. package/dist/presentation/queries-cli/overview.js.map +1 -1
  169. package/dist/presentation/structure.d.ts +1 -1
  170. package/dist/presentation/structure.d.ts.map +1 -1
  171. package/dist/presentation/structure.js +2 -2
  172. package/dist/presentation/structure.js.map +1 -1
  173. package/dist/types.d.ts +221 -0
  174. package/dist/types.d.ts.map +1 -1
  175. package/grammars/tree-sitter-gleam.wasm +0 -0
  176. package/package.json +7 -8
  177. package/src/cli/commands/audit.ts +2 -1
  178. package/src/cli/commands/batch.ts +1 -0
  179. package/src/cli/commands/build.ts +6 -1
  180. package/src/cli/commands/config.ts +353 -0
  181. package/src/cli/commands/triage.ts +1 -1
  182. package/src/cli/index.ts +10 -0
  183. package/src/cli/shared/options.ts +11 -1
  184. package/src/cli/types.ts +2 -0
  185. package/src/db/migrations.ts +8 -1
  186. package/src/domain/analysis/module-map.ts +29 -1
  187. package/src/domain/graph/builder/call-resolver.ts +263 -35
  188. package/src/domain/graph/builder/cha.ts +192 -0
  189. package/src/domain/graph/builder/context.ts +3 -0
  190. package/src/domain/graph/builder/helpers.ts +195 -5
  191. package/src/domain/graph/builder/incremental.ts +80 -1
  192. package/src/domain/graph/builder/pipeline.ts +49 -2
  193. package/src/domain/graph/builder/stages/build-edges.ts +867 -32
  194. package/src/domain/graph/builder/stages/detect-changes.ts +4 -2
  195. package/src/domain/graph/builder/stages/finalize.ts +4 -0
  196. package/src/domain/graph/builder/stages/native-orchestrator.ts +910 -43
  197. package/src/domain/graph/builder/stages/resolve-imports.ts +15 -1
  198. package/src/domain/graph/journal.ts +1 -1
  199. package/src/domain/graph/resolver/points-to.ts +254 -0
  200. package/src/domain/graph/resolver/ts-resolver.ts +536 -0
  201. package/src/domain/parser.ts +86 -17
  202. package/src/domain/wasm-worker-entry.ts +35 -2
  203. package/src/domain/wasm-worker-pool.ts +22 -0
  204. package/src/domain/wasm-worker-protocol.ts +15 -0
  205. package/src/extractors/c.ts +3 -3
  206. package/src/extractors/clojure.ts +1 -1
  207. package/src/extractors/cpp.ts +47 -4
  208. package/src/extractors/csharp.ts +33 -9
  209. package/src/extractors/cuda.ts +47 -4
  210. package/src/extractors/elixir.ts +6 -6
  211. package/src/extractors/fsharp.ts +1 -1
  212. package/src/extractors/go.ts +5 -5
  213. package/src/extractors/haskell.ts +1 -1
  214. package/src/extractors/helpers.ts +43 -0
  215. package/src/extractors/java.ts +10 -9
  216. package/src/extractors/javascript.ts +1929 -72
  217. package/src/extractors/kotlin.ts +5 -5
  218. package/src/extractors/lua.ts +1 -1
  219. package/src/extractors/objc.ts +3 -3
  220. package/src/extractors/ocaml.ts +1 -1
  221. package/src/extractors/php.ts +2 -2
  222. package/src/extractors/python.ts +7 -7
  223. package/src/extractors/ruby.ts +2 -2
  224. package/src/extractors/scala.ts +1 -1
  225. package/src/extractors/solidity.ts +1 -1
  226. package/src/extractors/swift.ts +4 -4
  227. package/src/extractors/zig.ts +4 -4
  228. package/src/features/structure-query.ts +7 -7
  229. package/src/index.ts +5 -1
  230. package/src/infrastructure/config.ts +494 -20
  231. package/src/infrastructure/native.ts +87 -5
  232. package/src/infrastructure/registry.ts +82 -1
  233. package/src/presentation/queries-cli/overview.ts +15 -1
  234. package/src/presentation/structure.ts +3 -3
  235. package/src/types.ts +235 -0
  236. package/grammars/tree-sitter-erlang.wasm +0 -0
@@ -122,9 +122,9 @@ function collectModuleMembers(
122
122
  ): void {
123
123
  for (let i = 0; i < doBlock.childCount; i++) {
124
124
  const child = doBlock.child(i);
125
- if (!child || child.type !== 'call') continue;
125
+ if (child?.type !== 'call') continue;
126
126
  const target = child.childForFieldName('target');
127
- if (!target || target.type !== 'identifier') continue;
127
+ if (target?.type !== 'identifier') continue;
128
128
 
129
129
  if (target.text === 'def' || target.text === 'defp') {
130
130
  const fnName = extractFunctionName(child);
@@ -184,7 +184,7 @@ function extractElixirParams(defCallNode: TreeSitterNode): SubDeclaration[] {
184
184
 
185
185
  for (let i = 0; i < args.childCount; i++) {
186
186
  const child = args.child(i);
187
- if (!child || child.type !== 'call') continue;
187
+ if (child?.type !== 'call') continue;
188
188
  const innerArgs = findChild(child, 'arguments');
189
189
  if (!innerArgs) continue;
190
190
  for (let j = 0; j < innerArgs.childCount; j++) {
@@ -277,13 +277,13 @@ function pushElixirMapValues(node: TreeSitterNode, stack: TreeSitterNode[]): voi
277
277
  const parts: TreeSitterNode[] = [];
278
278
  for (let i = 0; i < node.childCount; i++) {
279
279
  const content = node.child(i);
280
- if (!content || content.type !== 'map_content') continue;
280
+ if (content?.type !== 'map_content') continue;
281
281
  for (let j = 0; j < content.childCount; j++) {
282
282
  const kws = content.child(j);
283
- if (!kws || kws.type !== 'keywords') continue;
283
+ if (kws?.type !== 'keywords') continue;
284
284
  for (let k = 0; k < kws.childCount; k++) {
285
285
  const pair = kws.child(k);
286
- if (!pair || pair.type !== 'pair') continue;
286
+ if (pair?.type !== 'pair') continue;
287
287
  for (let p = 0; p < pair.childCount; p++) {
288
288
  const part = pair.child(p);
289
289
  if (!part || part.type === 'keyword') continue;
@@ -303,7 +303,7 @@ function handleValueDefinition(
303
303
  currentModule: string | null,
304
304
  ): void {
305
305
  const first = node.child(0);
306
- if (!first || first.type !== 'val') return;
306
+ if (first?.type !== 'val') return;
307
307
 
308
308
  const declLeft = findChild(node, 'value_declaration_left');
309
309
  if (!declLeft) return;
@@ -111,7 +111,7 @@ function extractGoReceiverType(receiver: TreeSitterNode): string | null {
111
111
  function handleGoTypeDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
112
112
  for (let i = 0; i < node.childCount; i++) {
113
113
  const spec = node.child(i);
114
- if (!spec || spec.type !== 'type_spec') continue;
114
+ if (spec?.type !== 'type_spec') continue;
115
115
  const nameNode = spec.childForFieldName('name');
116
116
  const typeNode = spec.childForFieldName('type');
117
117
  if (!nameNode || !typeNode) continue;
@@ -213,7 +213,7 @@ function extractGoImportSpec(spec: TreeSitterNode, ctx: ExtractorOutput): void {
213
213
  function handleGoConstDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
214
214
  for (let i = 0; i < node.childCount; i++) {
215
215
  const spec = node.child(i);
216
- if (!spec || spec.type !== 'const_spec') continue;
216
+ if (spec?.type !== 'const_spec') continue;
217
217
  const constName = spec.childForFieldName('name');
218
218
  if (constName) {
219
219
  ctx.definitions.push({
@@ -288,7 +288,7 @@ function inferAddressOfComposite(
288
288
  ): boolean {
289
289
  if (rhs.type !== 'unary_expression') return false;
290
290
  const operand = rhs.childForFieldName('operand');
291
- if (!operand || operand.type !== 'composite_literal') return false;
291
+ if (operand?.type !== 'composite_literal') return false;
292
292
  const typeNode = operand.childForFieldName('type');
293
293
  if (!typeNode) return false;
294
294
  const typeName = extractGoTypeName(typeNode);
@@ -409,7 +409,7 @@ function extractGoParameters(paramListNode: TreeSitterNode | null): SubDeclarati
409
409
  if (!paramListNode) return params;
410
410
  for (let i = 0; i < paramListNode.childCount; i++) {
411
411
  const param = paramListNode.child(i);
412
- if (!param || param.type !== 'parameter_declaration') continue;
412
+ if (param?.type !== 'parameter_declaration') continue;
413
413
  // A parameter_declaration may have multiple identifiers (e.g., `a, b int`)
414
414
  for (let j = 0; j < param.childCount; j++) {
415
415
  const child = param.child(j);
@@ -494,7 +494,7 @@ function extractStructFields(structTypeNode: TreeSitterNode): SubDeclaration[] {
494
494
  if (!fieldList) return fields;
495
495
  for (let i = 0; i < fieldList.childCount; i++) {
496
496
  const field = fieldList.child(i);
497
- if (!field || field.type !== 'field_declaration') continue;
497
+ if (field?.type !== 'field_declaration') continue;
498
498
  const nameNode = field.childForFieldName('name');
499
499
  if (nameNode) {
500
500
  fields.push({ name: nameNode.text, kind: 'property', line: field.startPosition.row + 1 });
@@ -123,7 +123,7 @@ function collectHaskellPatternBindings(node: TreeSitterNode, out: SubDeclaration
123
123
  case 'record':
124
124
  for (let i = 0; i < node.childCount; i++) {
125
125
  const fp = node.child(i);
126
- if (!fp || fp.type !== 'field_pattern') continue;
126
+ if (fp?.type !== 'field_pattern') continue;
127
127
  for (let j = 0; j < fp.childCount; j++) {
128
128
  const g = fp.child(j);
129
129
  if (g && g.type !== 'field_name') collectHaskellPatternBindings(g, out);
@@ -305,6 +305,49 @@ export function pushImport(
305
305
  ctx.imports.push(entry);
306
306
  }
307
307
 
308
+ // ── C-family primitive types ───────────────────────────────────────────────
309
+
310
+ /**
311
+ * Primitive C/C++/CUDA types that are never class/struct receivers. Seeding
312
+ * these into typeMap would produce spurious receiver edges (e.g. `int x` → `int`).
313
+ * Shared between the C++ and CUDA extractors to prevent divergence.
314
+ */
315
+ export const C_PRIMITIVE_TYPES: ReadonlySet<string> = new Set([
316
+ 'int',
317
+ 'long',
318
+ 'short',
319
+ 'unsigned',
320
+ 'signed',
321
+ 'float',
322
+ 'double',
323
+ 'char',
324
+ 'bool',
325
+ 'void',
326
+ 'wchar_t',
327
+ 'auto',
328
+ 'size_t',
329
+ 'uint8_t',
330
+ 'uint16_t',
331
+ 'uint32_t',
332
+ 'uint64_t',
333
+ 'int8_t',
334
+ 'int16_t',
335
+ 'int32_t',
336
+ 'int64_t',
337
+ 'ptrdiff_t',
338
+ 'intptr_t',
339
+ 'uintptr_t',
340
+ ]);
341
+
342
+ /**
343
+ * Return true when `typeName` is a primitive C/C++/CUDA type.
344
+ * Strips leading qualifiers (`const int` → `int`) before checking.
345
+ */
346
+ export function isCPrimitiveType(typeName: string): boolean {
347
+ const base = typeName.split(/\s+/).pop() ?? typeName;
348
+ return C_PRIMITIVE_TYPES.has(base) || C_PRIMITIVE_TYPES.has(typeName);
349
+ }
350
+
308
351
  // ── Parameter extraction ───────────────────────────────────────────────────
309
352
 
310
353
  /**
@@ -16,6 +16,7 @@ import {
16
16
  nodeStartLine,
17
17
  pushCall,
18
18
  pushImport,
19
+ setTypeMapEntry,
19
20
  } from './helpers.js';
20
21
 
21
22
  /**
@@ -273,13 +274,13 @@ function handleJavaLocalVarDecl(node: TreeSitterNode, ctx: ExtractorOutput): voi
273
274
  const child = node.child(i);
274
275
  if (child?.type === 'variable_declarator') {
275
276
  const nameNode = child.childForFieldName('name');
276
- // Use direct Map.set (last-wins) for local variable declarations.
277
- // Local variable types are method-scoped and should override any
278
- // prior entry (e.g. a same-named constructor parameter). Using
279
- // setTypeMapEntry (first-wins on tie) would let a constructor
280
- // parameter type block a local variable's more-specific concrete type.
281
- if (nameNode && ctx.typeMap)
282
- ctx.typeMap.set(nameNode.text, { type: typeName, confidence: 0.9 });
277
+ // Use setTypeMapEntry (first-wins on tie) to match Rust extractor semantics.
278
+ // The typeMap is flat per-file without method scoping, so a local variable
279
+ // in one method (e.g. `InMemoryUserRepository repo` in `createDefault()`) must
280
+ // not override a parameter binding set by an earlier method
281
+ // (e.g. `UserRepository repo` constructor param). First-wins preserves the
282
+ // interface/abstract type annotation that drives correct CHA dispatch.
283
+ if (nameNode && ctx.typeMap) setTypeMapEntry(ctx.typeMap, nameNode.text, typeName, 0.9);
283
284
  }
284
285
  }
285
286
  }
@@ -330,7 +331,7 @@ function extractClassFields(classNode: TreeSitterNode): SubDeclaration[] {
330
331
  if (!body) return fields;
331
332
  for (let i = 0; i < body.childCount; i++) {
332
333
  const member = body.child(i);
333
- if (!member || member.type !== 'field_declaration') continue;
334
+ if (member?.type !== 'field_declaration') continue;
334
335
  extractFieldDeclarators(member, fields);
335
336
  }
336
337
  return fields;
@@ -341,7 +342,7 @@ function extractFieldDeclarators(member: TreeSitterNode, fields: SubDeclaration[
341
342
  const vis = extractModifierVisibility(member);
342
343
  for (let j = 0; j < member.childCount; j++) {
343
344
  const child = member.child(j);
344
- if (!child || child.type !== 'variable_declarator') continue;
345
+ if (child?.type !== 'variable_declarator') continue;
345
346
  const nameNode = child.childForFieldName('name');
346
347
  if (nameNode) {
347
348
  fields.push({