mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
13 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3d4a95360d
|
fix(java): materialize record component accessors (#2936)
* fix(java): materialize record component accessors * fix(java): ignore receiver params in record accessor arity * fix(java): address record-accessor review findings (#2917) Five findings from the tri-review of #2936. P1 — a synthesized callable evicted a source-written one from the method map. `getMethodInfo` keyed its per-class map by `name:line`, but a callable that is SYNTHESIZED at a position that is not its own declaration shares its owner's line: a record's implicit accessor is minted at the component, and a C# 12 primary constructor at the owner's `parameter_list`. Both are appended last by their extractor, so on a single line the synthesized entry overwrote the explicit method's MethodInfo and both definitions collapsed onto one id — `record P(int x, int y) { int x(int s) {...} }` lost `P.x#1` and rebound the arity-1 call to the zero-argument accessor. Adds a required `MethodInfo.column` and keys the map by `name:line:column` through a single `methodInfoKey` helper. Required, not optional: an absent column would key an entry no lookup could reach — a silent, whole-language loss of enrichment instead of a compile error. All three lookup sites move together; the file's own lockstep docblock warns that a half-applied change loses caller edges silently rather than dangling. This also fixes the same collision in C#, which never touched record code. Degenerate component names no longer mint a node. tree-sitter's zero-width MISSING recovery token satisfies `name: (identifier)`, so `record M(int x, y) {}` minted an empty-named Method whose returnType was the neighbouring `y`; and the grammar admits `underscore_pattern` in the same field, which the query rejected but the scope path accepted, so `record R(int _) {}` left a scope declaration with no node behind it. One `isRecordComponentName` predicate now gates all three emitters — query suppression, scope synthesis, and the method extractor — so they cannot drift apart again. Component annotations reach the implicit accessor (JLS 8.10.3 / 9.7.4) by reusing the shared `extractAnnotations` helper. Deliberately over-approximate and commented as such: `@Target` lives in another file and parsing is per-file. `explicitZeroArgAccessorNames` is memoised per record node. It was rebuilt on every component capture — O(components x body members) for one record, measured at ~4x per 2x input — while the scope path already hoisted the identical call. Docs: the `java-local-types` baseline now stores the `capture_groups_fp` its own note cites, the SCHEMA_BUMP ledger no longer claims a v65 that nothing holds, and `shouldSkipDefinitionCapture` documents that `defaultLabel` may be ignored. Scope-capture fingerprints are unchanged (`measure.mjs --check` PASS, 15 languages): the bench corpus contains no degenerate components, so the new predicate is inert on it. SCHEMA_BUMP stays 67 — this branch's existing claim already covers the changed worker output; re-check it against origin/main before merging. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Px638Zyqa9CJMUU7DsJoB * docs(ingestion): reunite the overload-suffix JSDoc with typeTagForId The block describing the `~type1,type2` same-arity discriminator was stranded above `buildCollisionGroups` when that function was inserted between it and the `typeTagForId` it documents (#658). Adding `methodInfoKey` in this branch parked it directly above yet another unrelated function, which gitnexus-check flagged. Moves the comment down to the function it describes. No behaviour change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Px638Zyqa9CJMUU7DsJoB --------- Co-authored-by: Gergő Magyar <gergomagyar@icloud.com> Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e26002c37a
|
fix(cpp): suppress deleted overload winners (#2094)
* fix(cpp): suppress deleted overload winners * test(cpp): update scope capture fingerprint --------- Co-authored-by: Gergő Magyar <gergomagyar@icloud.com> |
||
|
|
2870aa6248
|
fix(grammars): load vendored tree-sitter grammars from vendor/ by absolute path (#2111) (#2144)
* fix(grammars): load vendored tree-sitter grammars from vendor/ by absolute path (#2111) The recurring Windows `EPERM: operation not permitted, symlink` (errno -4048) when adding the MCP server to Antigravity is NOT the #2101/#2110 module-load crash — it is an install-time arborist failure during the `_npx` reify that the MCP client triggers on every `npx gitnexus` launch. Root cause: the `postinstall` materialize step copied each vendored grammar (`vendor/tree-sitter-{c,dart,proto,swift,kotlin}`) into `node_modules/gitnexus/node_modules/tree-sitter-*` as a real package so runtime `require('tree-sitter-dart')` would resolve. Those packages are in no dependency graph, so every subsequent npm/npx reify treats them as **extraneous** and prunes/relocates them — on Windows the relocation goes through `@npmcli/move-file`'s symlink path and throws EPERM (symlinks need Developer Mode/admin), and on every OS the 2nd run silently deletes the grammars. This is the same class as #1728, which the materialize step itself claimed to have fixed. Fix (the prebuildify + node-gyp-build ecosystem pattern): never copy grammars into node_modules. Load each by absolute path from `vendor/<name>` via the new `requireVendoredGrammar` helper — the grammar's own `bindings/node` runs `node-gyp-build(<dir>)` and loads the committed `vendor/<name>/prebuilds/ <platform>-<arch>/…` directly (all 5 ship all 6 tuples). vendor/ is inside the package but not a node_modules subtree, so arborist never sees the grammars and the reify is idempotent — no EPERM, no silent deletion. - new src/core/tree-sitter/vendored-grammars.ts (requireVendoredGrammar / vendoredGrammarDir / VENDORED_GRAMMAR_PACKAGES; VENDOR_ROOT stable in dev+dist) - route all consumers through it: parser-loader, parse-worker, grpc proto, include-extractor (C), http-patterns kotlin, cli optional-grammars probe - postinstall drops the materialize step; build-tree-sitter-grammars.cjs builds in-place under vendor/ (gitignored) and deletes materialize-vendor-grammars.cjs - tests + grammar-introspection helper load grammars from vendor/ too (single source of truth); new vendored-grammars.test.ts guards against reintroducing a bare `require('tree-sitter-<vendored>')` Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(grammars): throw on a non-vendored name in requireVendoredGrammar Drift guard (PR #2144 review, P3): validate the argument against VENDORED_GRAMMAR_PACKAGES and fail loudly on an unknown name, so the three grammar lists (package set / CLI probe / build registry) drifting out of sync surfaces as a clear error instead of a confusing absolute-path require miss. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(grammars): prepack guard against stray vendor/<g>/build/ shadowing prebuilds Publish hygiene (PR #2144 review, P2). Now that build-tree-sitter-grammars.cjs source-builds into vendor/<name>/build/, a stray build dir would ship in the tarball (files:["vendor"] overrides .gitignore/.npmignore) AND shadow the committed prebuild — node-gyp-build resolves build/Release before prebuilds/. assert-publish-grammar-coverage.cjs (prepack) now fails `npm pack` if any vendor/*/build exists (findStrayBuildArtifacts), with a clear `rm -rf` fix hint. Adds unit coverage for the new pure function. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(grammars): harden the #2111 no-bare-require regression guard PR #2144 review (P2). The guard regex missed dynamic import(), side-effect `import 'x'`, /subpath, and backtick loads, and only scanned src/. It now covers every node_modules-forcing form (single/double/backtick quotes, optional subpath), scans test/ too (excluding fixtures and the guard file itself), drops the `//`-substring false-negative (leading-comment-only heuristic), and adds a self-test asserting every load form is caught while prose mentions and tree-sitter-cpp are ignored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(grammars): correct stale vendored-grammar comments PR #2144 review (P3). kotlin/query.ts called tree-sitter-kotlin an "optionalDependency" — it is vendored and loaded from vendor/ by absolute path (#2111). proto.ts now states its remaining `_require` is only for the real `tree-sitter` dependency, not a vendored grammar (which goes through requireVendoredGrammar). Comment-only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
df5ce1f49b
|
fix(ingestion): close remaining open language parsing-layer coverage gaps (#1919) (#2072)
* fix(c): skip computed #include MACRO instead of emitting a garbage import source (F5) * fix(cpp): emit a Variable per name for structured-binding declarations (F9) * fix(dart): extract static const/final class fields (F26) * fix(dart): capture old-style function typedefs (F28) * fix(dart): read real top-level variable shape instead of a dead type field (F29) * fix(kotlin): capture callable references (F47) * fix(kotlin): anchor infix-call capture to the operator only (F49) * fix(kotlin): extract secondary constructors as members (F48) * fix(kotlin): capture destructuring declarations (F51) * fix(kotlin): index companion-object properties as fields (F52) * test(kotlin): assert callable-reference coverage runs on the worker path (F47) * fix(swift): extract protocol property requirements (F75) * fix(swift): recognize enum_class_body as a method body node (F79) * test(ingestion): rebaseline swift captures-golden + scope-capture fingerprints (#1919) * fix(kotlin): attribute secondary-constructor body calls to the Constructor node (#1919 review CF1) A Kotlin secondary constructor's body executes statements like a method body, but the registry-primary scope-resolution path had no Function scope or Constructor def for it. A call inside the body resolved its caller anchor up to the enclosing Class scope, mis-attributing the CALLS edge to the class rather than the Constructor. Add `(secondary_constructor) @scope.function` to the Kotlin scope query so the body becomes its own scope, and synthesize a `@declaration.constructor` (named `constructor`, qualified `<Class>.constructor`, with parameter metadata) so the scope owns a Constructor def that bridges to the structure-phase Constructor node. Also add an arity-disambiguating lookup key for overloadable callables: two same-name secondary constructors of different arity (e.g. a zero-arg vs a 2-arg) share the qualified key whose first-write-wins assignment is source-order- dependent — so a zero-arg overload could resolve to a sibling. The structure node id encodes `#<arity>`; mirror that in the bridge keyspace and match by the def's parameterCount. Same-arity overloads collapse onto one arity key exactly as before, so no regression there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(kotlin): do not own function-local property bindings under the enclosing class (#1919 review CF3) Kotlin emits destructuring / loop bindings (`val (a,b) = pair`, `for ((k,v) in m)`) as `@definition.property` to dodge the block-scope local-symbol pruner. When such a binding sits inside a method body of a class, the structure-phase owner walk found the enclosing class and emitted a spurious HAS_PROPERTY edge (e.g. `C -> k`), treating a function-local as a class member. Guard the Property owner resolution: if a function-like ancestor is reached before any class container, the property is function-local and gets no owner edge (it falls back to a File DEFINES edge). Language-agnostic — genuine class fields sit directly in the class body with no intervening function, so they keep their HAS_PROPERTY owner edge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(kotlin): guard non-companion property isStatic=false (#1919 review CF4) Add a field-extraction case for a plain non-companion class `class C { val x: Int = 1 }` asserting the property `x` has isStatic=false, guarding the `isInsideKotlinCompanion` walk against false-positives. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(kotlin): dedup type_identifier lookup in extractOwnerName (#1919 review CF5) The `node.namedChildren.find(c => c.type === 'type_identifier')?.text` lookup was duplicated across the companion and non-companion branches of the Kotlin field-extractor's extractOwnerName. Hoist it into a single local, preserving the existing behavior (anonymous companion falls back to "Companion"; other nodes prefer the `name` field, else the type_identifier text, else undefined). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(dart): capture generic old-style function typedefs (#1919 review CF2) * test(dart): guard multi-name field count and top-level-var labels (#1919 review CF4) * docs(swift): correct isStatic comment re multi-modifier hasKeyword (#1919 review CF5) * test(ingestion): rebaseline dart+kotlin scope-capture fingerprints after review remediation (#1919) * fix(ingestion): correct CF3 owner-strip boundary set for accessor/init bodies and Dart signatures (#1919 review) The CF3 property-ownership guard used FUNCTION_NODE_TYPES, which (a) includes Dart bare signatures (function_signature/method_signature) — over-stripping every Dart class getter/setter's HAS_PROPERTY owner — and (b) omits Kotlin anonymous_initializer/getter/setter and Swift computed accessors — under- stripping destructuring/locals inside init{} and accessor bodies, emitting spurious Class->local HAS_PROPERTY edges. Introduces a guard-specific LOCAL_SCOPE_BODY_NODE_TYPES set (signatures excluded, accessor/init bodies included). Adds Dart accessor-ownership + Kotlin init/accessor destructuring regression fixtures. Both confirmed on the worker pipeline; no cross-language regression (1597 cross-language tests green). --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
c4ee911463
|
fix(kotlin): detect default parameter arity (#2034)
* fix(kotlin): detect default parameter arity * test(kotlin): rebaseline optional arity captures * test(kotlin): cover default parameter boundaries |
||
|
|
1f6df5fdbb
|
fix(swift): use official prebuilt parser runtime (#1130)
* fix(swift): use official prebuilt parser runtime Vendor the official tree-sitter-swift 0.7.1 runtime package so Swift parsing works without source-building, while keeping the repo on the current tree-sitter runtime until the broader upgrade is ready. Also preserves Swift resolver correctness for overloaded owned functions and extension-backed type duplicates now that Swift is available by default. Made-with: Cursor * fix(swift): move duplicate type ordering into provider Keep Swift extension candidate ordering behind the LanguageProvider contract and cover the Swift 0.7 init scanner path so parser runtime changes do not leak language-specific logic into shared resolution. Made-with: Cursor * fix(swift): address parser runtime review Add explicit Swift prebuild checks and vendor guidance so parser runtime packaging remains observable and maintainable. |
||
|
|
26ff700e37
|
refactor(pipeline): DAG-based phase architecture + container-logic extraction to LanguageProvider (#809)
* Initial plan * refactor: move language-specific container node logic into LanguageProvider - Add resolveEnclosingOwner hook to LanguageProviderConfig - Add staticOwnerTypes to MethodExtractionConfig - Implement Ruby resolveEnclosingOwner (singleton_class → class/module) - Replace hardcoded STATIC_OWNER_TYPES with config.staticOwnerTypes - Move Ruby static types to rubyMethodConfig - Move Kotlin static types to kotlinMethodConfig - Remove Ruby singleton_class branch from findEnclosingClassInfo - Collapse seqFindEnclosingClassNode/seqFindRawEnclosingContainerNode into single provider-aware seqFindEnclosingOwnerNode - Update worker path to pass provider.resolveEnclosingOwner Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/bc9f9d4d-f749-4872-9ff2-17fc86e08787 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * test: add regression tests for config-driven staticOwnerTypes and resolveEnclosingOwner hook Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/bc9f9d4d-f749-4872-9ff2-17fc86e08787 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * refactor: implement DAG-based pipeline architecture with phase extraction Restructure the ingestion pipeline from a ~1800-line monolithic orchestrator into a DAG (Directed Acyclic Graph) of named phases with explicit dependencies. New files under pipeline-phases/: - types.ts: PipelinePhase, PipelineContext, PhaseResult contracts - runner.ts: DAG runner with topological sort validation - scan.ts, structure.ts, markdown.ts, cobol.ts: early phases - parse.ts + parse-impl.ts: chunked parse + resolve (the core) - routes.ts, tools.ts, orm.ts: post-parse enrichment phases - cross-file.ts + cross-file-impl.ts: cross-file binding propagation - mro.ts, communities.ts, processes.ts: graph analysis phases - index.ts: barrel export pipeline.ts reduced from ~1960 lines to ~184 lines: - DAG phase array declaration - runPipelineFromRepo as thin orchestrator - topologicalLevelSort retained for backward compat Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c * test: add DAG runner unit tests, update ARCHITECTURE.md with phase DAG docs Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c * fix: address code review - pass resolutionContext through parse output, fix worker URL path Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c * fix: declare transitive parse dependency explicitly in mro/communities/processes phases Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c * refactor: improve pipeline-phases clean code and folder structure - Extract synthesizeWildcardImportBindings to wildcard-synthesis.ts - Extract extractORMQueriesInline to orm-extraction.ts - Create shared constants.ts for AST_CACHE_CAP - Fix inline type import in orm.ts (use proper top-level import) - Add comprehensive JSDoc to getPhaseOutput explaining type safety - Move isDev to module level in cross-file.ts (consistency) - Improve module-level documentation across files - Organize barrel exports in index.ts with section comments Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/2bd6d4aa-6271-4009-8dd2-332ea8ec73ab Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * address review feedback: fix circular dep, allFetchCalls mutation, progress bugs, remove DAG naming, extract isDev, fix _item naming, fix O(n²) line calc Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/6cf53c9b-d55d-4c6f-bf3d-7bfb82d512b6 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * improve JSDoc on lineNumberAtOffset binary search Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/6cf53c9b-d55d-4c6f-bf3d-7bfb82d512b6 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * address review: filter deps in runner, move totalFiles to ctx, fix cycle JSDoc, centralize isDev, remove DAG naming Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b388424f-b939-4a94-97de-3855f9465564 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * fix doc consistency in graph-sort.ts module-level and function-level JSDoc Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b388424f-b939-4a94-97de-3855f9465564 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * fix(pipeline): wrap phase errors with phase name and emit terminal error progress event Restores phase diagnostics at CLI/MCP boundary. runPipeline now wraps phase.execute() in try/catch and rethrows with 'Phase <name> failed: ...' preserving the original via { cause }. Also emits a terminal { phase: 'error' } progress event so subscribers see the failure before the rejection propagates. Handler errors during error reporting are swallowed to keep the original cause authoritative. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U1) * fix(pipeline): move bindingAccumulator dispose into crossFile try/finally; make single-use crossFile.execute() now wraps its body in try/finally so the accumulator is released on both the happy path and when runCrossFileBindingPropagation throws. Dev-mode telemetry stays inside the try block before dispose (all three counters return 0 after dispose clears internal maps). BindingAccumulator becomes single-use: appendFile after dispose now throws 'BindingAccumulator: use after dispose' instead of silently re-animating via the old _disposed auto-clear. Docs updated; the only production construction site (parse-impl) always creates a fresh instance per run, so no caller relied on the re-use contract. Residual risk documented in crossFile module JSDoc: a future phase inserted between parse and crossFile that throws would still leak the accumulator. Any such phase must manage accumulator lifetime explicitly. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U2) * docs(pipeline): explain why importCtx teardown is safe before crossFile Investigation (plan U3) confirms: `importCtx` (ImportResolutionContext) is a scratch workspace with no downstream consumer after parse. `resolutionContext` (returned to crossFile) is a distinct object that owns importMap / namedImportMap / packageMap / moduleAliasMap / model, and never closes over importCtx. cross-file-impl consumes only that ctx via processCalls. The two confusingly-similar "context" names were the root of the adversarial reviewer's concern — comment locks in the invariant so the next reader sees it. No behavioral change. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U3) * refactor(pipeline): remove ctx.totalFiles side-channel; promote to ParseOutput totalFiles was a hidden mutable field on PipelineContext written by parse and read by mro/communities/processes — five reviewers flagged this as a violation of the immutable-context invariant. Removed from PipelineContext, which is now fully readonly, and made the implicit temporal dep explicit: mro/communities/processes now declare 'parse' as a dep and read totalFiles via getPhaseOutput<ParseOutput>(...). No behavior change. Topo-sort unchanged because parse was already a transitive dep through crossFile. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U4) * feat(method-extractor): runtime staticOwnerTypes guard at factory chokepoint createMethodExtractor now rejects MethodExtractionConfigs that list companion_object / singleton_class / object_declaration in typeDeclarationNodes but omit the matching entry from staticOwnerTypes. Fails loudly at provider construction time instead of producing silent isStatic=false on the 50000th file analyzed. Opt-out convention preserved: an explicit `new Set()` (empty Set) signals intentional exclusion and passes the guard (memory obs #30588). All 13 existing language configs pass the guard; the new negative test fails without it. Test-first. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U5) * fix(pipeline): wrap sequential-fallback in try/finally so cleanup survives throws The sequential-fallback block in runChunkedParseAndResolve now runs inside a try/finally that guarantees astCache.clear(), accumulator finalize, and enrichExportedTypeMap execute even if readFileContents or processCalls throws mid-fallback. Cleanup failures are caught inside the finally so they can't mask the original error. Accumulator disposal ownership remains with crossFile (U2) — U6 only adds astCache cleanup and preserves finalize ordering on the error path. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U6) * test(pipeline): direct unit coverage for wildcard-synthesis and cross-file-impl Both modules previously had zero direct unit coverage — branches were exercised only through integration tests' happy paths. wildcard-synthesis.test.ts covers: Go graph-IMPORTS fallback, Python moduleAliasMap build, MAX_SYNTHETIC_BINDINGS_PER_FILE cap, dedup against existing namedImportMap entries, and empty-exportedSymbols early return. cross-file-impl.test.ts covers: gapRatio below threshold no-op, MAX_CROSS_FILE_REPROCESS cap, graph-only exportedTypeMap fallback, and empty namedImportMap short-circuit. Tests assert current behavior — any future regression flips them. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U7) * test(pipeline): golden-file graph-parity regression guard on mini-repo fixture Pins the current post-P1/P2 graph output (57 symbols, 92 relationships, 4 processes, deterministic edge digest) so future silent refactors cannot drift behavior unnoticed. If any count changes or any edge rewires, the test fails with a readable diff listing what changed and a copy-pasteable UPDATE_GOLDEN=1 regen command. Edge digest keyed by symbolic (label, name, filePath) triples rather than raw generateId output — stays meaningful across id-encoding refactors while still catching real semantic rewiring. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U8) * fix(pipeline): minimal cycle reporting + resolveEnclosingOwner loop safeguards U9: runner cycle detection now reports only the SCC members via DFS back-edge trace ('Cycle detected: A -> B -> C -> A') rather than everything with inDegree > 0 (which mixed cycle members with blocked dependents). Also emits the 'error' progress event for graph- validation failures, symmetric with U1's runtime-error path. U16: findEnclosingClassInfo now defends against language-provider hooks that return non-container nodes — visitedContainers Set breaks repeat-visit loops, MAX_ENCLOSING_WALK_ITERATIONS is belt-and-braces. Documented the hook contract invariant so future provider authors know the walk-continues-upward expectation. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U9, U16) * refactor(pipeline): type hygiene, dead code cleanup, shared allPathSet, graph-sort naming Bundles plan units U10, U11, U12, U14, U15: U10 — Type hygiene: readonly ParseOutput arrays (allExtractedRoutes, allDecoratorRoutes, allToolDefs, allORMQueries, allPaths); removed redundant 'as string[] | undefined' cast in routes.ts and 'as URL' in parse-impl.ts; WorkerPool is now 'import type'. Readonly contract propagated into processORMQueries (only iterates). U11 — Dead code & shims: deleted constants.ts shim (AST_CACHE_CAP inlined into its sole real consumer cross-file-impl.ts; isDev consumers now import directly from ../utils/env.js). Removed internal utility re-exports from pipeline-phases/index.ts (no external consumers). Removed topologicalLevelSort re-export from pipeline.ts; updated topological-sort.test.ts to import from the canonical utils/graph-sort.js. Stripped 'Phase 3+4:' stale JSDoc from parse-impl.ts. U12 — Perf: StructureOutput now carries allPathSet (ReadonlySet<string>) built once; cobol, markdown, and cross-file-impl consume the shared set instead of allocating their own. Parse forwards it via ParseOutput.allPathSet; processCobol/processMarkdown widened to ReadonlySet<string>. U14 — graph-sort.ts: renamed local 'inDegree' to 'pendingImportsPerFile' with expanded JSDoc explaining the reverse- graph Kahn's formulation and warning future maintainers not to 'correct' it to standard in-degree semantics. Added self-edge test. U15 — Unconditional worker-fallback logging: removed isDev guard on the worker-pool-creation-failure console.warn so operators can diagnose perf degradations in production. No behavior change. U8 golden-file test confirms pipeline output is byte-identical. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U10, U11, U12, U14, U15) * docs: fix ARCHITECTURE.md table integrity; bump AGENTS.md/CLAUDE.md to 1.3.0 U13 — documentation fixes: ARCHITECTURE.md: the prior insertion of the 'Pipeline Phase DAG' section orphaned 7 rows from the 'Where to change what' header. Moved those 7 rows back up under their header so the table reads contiguously; DAG section now follows the completed table. AGENTS.md + CLAUDE.md: bumped version 1.2.0 -> 1.3.0, updated Last reviewed to 2026-04-13, added matching Changelog row documenting the GitNexus index stats refresh after the DAG refactor. Stat bumps (symbols/relationships/execution flows) that were sitting uncommitted in the working tree are now landed under a proper changelog entry per each file's own documented schema. Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U13) * refactor(pipeline): drop spurious parse deps, true-readonly ParseOutput.exportedTypeMap, skip redundant wildcard synth - mro/communities/processes: switch redundant `parse` dep to `structure` — totalFiles originates in structure, so depending on parse for it was a spurious data dep that obscured the real DAG. - ParseOutput.exportedTypeMap: typed as truly ReadonlyMap<...,ReadonlyMap>>; graph→exports enrichment moved into parse-impl so the snapshot is fully populated at parse return. crossFile builds its own local mutable working copy for per-file re-resolution writes — no cast at the boundary. - parse-impl: hasSynthesized flag guards the unconditional final synthesizeWildcardImportBindings call when per-chunk/fallback synthesis already ran (graph-global + idempotent across chunks). - cross-file-impl: documented the intentional `phase: 'parsing'` progress label so telemetry bucketing stays consistent with the parse phase. - cross-file-impl test: replaced the now-moved fallback-enrichment assertion with a stronger one — crossFile must not mutate the parse-supplied map. Addresses PR #809 review pass 5 carry-overs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> Co-authored-by: Gergo Magyar <gergomagyar@icloud.com> |
||
|
|
5a7c0fdbb1
|
feat: same-arity overload disambiguation via type-hash suffix (#651) (#658)
* feat: same-arity overload disambiguation via type-hash suffix (#651) Add ~type1,type2 suffix to Method/Constructor node IDs when same-arity overloads with different parameter types exist in the same class. Also add $const suffix for C++ const-qualified method overloads via new isConst field. Key changes: - typeTagForId() detects same-arity collisions and appends ~typeTag - constTagForId() detects const/non-const collisions and appends $const - TS/JS excluded from type-hashing (overload signatures collapse to impl body) - Sequential findEnclosingFunction fixed: falls through on ambiguous same-class candidates instead of picking first; fallback path includes typeTag + constTag - Per-call-site integration tests across Java, C#, Kotlin, C++, TypeScript - Cross-file + chain resolution tests for all 5 languages - C++ isConst extraction via tree-sitter type_qualifier in function_declarator 1710 integration + 18 unit tests pass. * fix: preserve generic/template args in type-hash, perf + type safety fixes - Add rawType field to ParameterInfo preserving full type text (vector<int>) while type stays simplified (vector). typeTagForId uses rawType for tags. - Populate rawType in all 11 language method extractors - Add buildCollisionGroups() to pre-group methods by name#arity (O(N) once per class instead of O(N) per method call) - Cache method extraction in call-processor findEnclosingFunction fallback - Fix null guards on getLanguageFromFilename in all findEnclosing paths - Tighten SKIP_TYPE_HASH_LANGUAGES to ReadonlySet<SupportedLanguages> - Document ID stability invariant on first overload introduction - C++ integration tests: template overloads (vector<int> vs vector<string>), cross-file template + chain resolution, out-of-class method definitions 1718 integration + 20 unit tests pass. * fix: add rawType to method-extraction unit test assertions All 26 parameter .toEqual() assertions in method-extraction.test.ts needed the new rawType field added to match ParameterInfo schema change. * perf: cache tempMap/groups per class, consolidate extractFromNode - Cache derived method map + collision groups per classNode.id in parsing-processor (avoids rebuild per method in same class) - Replace per-call extractFromNode with cached class extraction + funcName:line lookup in call-processor fallback (avoids AST walk per call site) - Remove dead clearEnclosingFunctionCache export, fix JSDoc * test: add sequential-path integration test for same-arity overloads Add skipWorkers option to PipelineOptions to force sequential parsing. New test suite verifies type-hash disambiguation produces identical results through the sequential path (parsing-processor + call-processor findEnclosingFunction) as the worker path. |
||
|
|
63fc4c795f
|
feat: MethodExtractor configs for Python, PHP, Swift, Dart, Rust, Ruby (#624)
* feat: MethodExtractor configs for Python, PHP, Swift, Dart, Rust, Ruby with exhaustive integration tests Add per-language MethodExtractionConfig for all remaining tree-sitter languages (RFC #568 PR 2). Each config follows the established createMethodExtractor() factory pattern — no new types, no parse-worker changes. Configs: - Python: @abstractmethod, @staticmethod/@classmethod, *args/**kwargs, type hints, _/__ visibility - PHP: abstract/final/static keywords, PHP 8 #[] attributes, __construct/__destruct - Swift: 5-level visibility, protocol-as-abstract, static/class methods, @ attributes - Dart: _ convention visibility, abstract (no body), method_signature unwrapping - Rust: pub visibility, &self receiver, trait_item + impl_item, #[] attributes - Ruby: positional visibility via sibling-walk, singleton_method as static Integration fixtures (18 directories) covering 3 resolution patterns: - Method enrichment: parameterTypes, isAbstract, isFinal, annotations on graph nodes - Overload dispatch: arity-based CALLS resolution via parameterTypes - Abstract dispatch: abstract/concrete method distinction (Python, PHP, Rust, Swift) Go deferred — requires factory changes for receiver-based method extraction. Closes #571 * fix: address code review findings across 6 MethodExtractor configs Fix all actionable items from the PR #624 deep-dive review: Dart (critical — fixes 6 CI failures): - isDartStatic: check children first, siblings as fallback - isDartAbstract: handle declaration nodes for abstract methods - extractSingleParam: detect required keyword as sibling token - Add declaration to methodNodeTypes, mixin_declaration to typeDeclarationNodes - Add member call query for variable assignments in tree-sitter-queries Python: - hasDecorator now matches dotted paths (e.g. @abc.abstractmethod) - Fix version comment from ^0.23.6 to 0.23.4 PHP: - Add enum_declaration to typeDeclarationNodes (PHP 8.1+) - Add version comment for 0.23.12 Swift: - Add isOverride using hasKeyword/hasModifier pattern Rust: - Fix version comment from ^0.23.2 to 0.23.1 Also: identifier fallback in generic.ts for mixin owner names, Dart integration test label fix (Method vs Function), version comment for tree-sitter-dart 1.0.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Dart extension_declaration and Ruby module_function support Dart: - Add extension_declaration to typeDeclarationNodes and extension_body to bodyNodeTypes — extension methods are now extracted into the graph - Add extension_declaration and mixin_declaration to CLASS_CONTAINER_TYPES for HAS_METHOD edge resolution Ruby: - module_function now maps to visibility 'private' in extractRubyVisibility - module_function methods marked isStatic via backward-walk in isStatic - Override semantics: private/public after module_function resets isStatic Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(go): Go MethodExtractor config with receiver-based extraction Add Go as the 13th language with a per-language MethodExtractor config. Go methods are top-level (not nested in struct bodies), so this adds extractFromNode() to the MethodExtractor interface for direct method node extraction without an enclosing class. Config extracts: - Name from field_identifier (methods) / identifier (functions) - Return type including multi-return (first type from parameter_list) - Parameters with variadic support - Visibility via uppercase/lowercase convention - Receiver type with pointer unwrapping (*User → User) - isStatic for functions (no receiver) Infrastructure: - extractOwnerName optional hook on MethodExtractionConfig - extractFromNode on MethodExtractor (factory auto-implements) - Parse-worker uses extractFromNode when no enclosing class found - method_declaration added to CLASS_CONTAINER_TYPES Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: method enrichment integration tests for 7 languages + TS abstract class fix Add method-enrichment integration test fixtures and test blocks for Go, C++, Java, Kotlin, TypeScript, JavaScript, and C#. Each fixture tests: class detection, HAS_METHOD edges, EXTENDS edges, isAbstract, isStatic, annotations, parameterTypes, and CALLS edge resolution. Fixes found during testing: - Remove method_declaration from CLASS_CONTAINER_TYPES (added for Go but broke Java/C# HAS_METHOD edge resolution — method_declaration is also Java's method node type) - Add abstract_class_declaration query to TypeScript tree-sitter queries (was missing, so abstract classes were invisible to pipeline) 1699 integration tests pass across 20 test files, 0 regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: format typeDeclarationNodes array for better readability in PHP config * fix: Go interface methods + Rust impl-for-Struct owner resolution Go: - Add method_elem to methodNodeTypes so interface method signatures are extractable as abstract methods - Integration test: Animal interface detected, Speak isAbstract, CALLS edges from app.go Rust: - Add extractOwnerName to resolve impl Trait for Struct to the concrete Struct (not the Trait) — fixes method misattribution - Fix findEnclosingClassId to generate Struct: label (not Impl:) for impl blocks so HAS_METHOD edges resolve to struct nodes - Tighten abstract-dispatch test: assert SqlRepo owns find/save generic.ts: - Fix extractOwnerName fallback: when hook returns a value, skip both name-field and type_identifier scan (was overwriting result) 1703 integration tests pass, 0 regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: code review response — Rust impl label, Swift params, Dart async, sequential methodExtractor Address code review findings from PR #624: - ast-helpers: Rust `impl Trait for Struct` uses Struct label (matches existing graph node), plain `impl Struct` uses Impl label (matches definition.impl) - swift: fix parameter type extraction (user_type not type_annotation), detect default values as function_declaration siblings, add version comment - dart: isDartAsync now detects async*/sync* generators, add clarifying comment for declaration nodes in extension bodies - python: correct isFinal comment (PEP 591 @typing.final exists, just not modeled) - parsing-processor: port methodExtractor enrichment to sequential path so isAbstract/isStatic/visibility/annotations/isFinal populate on <15-file repos - tests: remove silent `if (prop !== undefined)` guards, assert properties directly, fix label queries (Dart Method vs Function, Swift Method for protocol methods), add Rust HAS_METHOD sourceLabel tests, Swift parameterTypes tests, and Dart async/sync* integration tests with fixture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Rust grammar gap + qualified method IDs to resolve same-file collisions Phase 1 — Rust grammar: - Add function_signature_item query to RUST_QUERIES so abstract trait methods (fn speak(&self) -> String;) become graph nodes with isAbstract=true Phase 2 — Qualified method IDs: - findEnclosingClassInfo returns {classId, className} for AST-based class lookup - Both parsing paths (sequential + worker) qualify method/property IDs with enclosing class: Method:file:ClassName.method instead of Method:file:method - extractFuncNameFromSourceId handles ClassName.method format - Fixes silent data loss when same-name methods in different classes shared a file (e.g., Animal.speak and Dog.speak both now exist as distinct graph nodes) Test updates: - Rust: abstract+concrete trait methods both verified, function count adjusted - Python: static method disambiguation now emits 2 CALLS edges (correct — no more ID collision masking the second call) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: owner-aware resolution for qualified method IDs Address Codex adversarial review findings after qualified ID change: - findEnclosingFunction: disambiguate candidates by ownerId when multiple same-name methods exist in file; qualify fallback-generated IDs - findEnclosingFunctionId (worker): qualify sourceIds with enclosing class name so CALLS source attribution matches definition-phase node IDs - buildExportedTypeMapFromGraph: use lookupExactAll + nodeId match instead of lookupExactFull which returns first definition for bare name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: methodExtractor variadic arity, return type preservation, PHP abstract dispatch Three bugs in the methodExtractor enrichment path broke 17 integration tests: 1. Variadic parameterCount: buildMethodProps and parse-worker set parameterCount = info.parameters.length even for variadic functions, causing arity filtering to reject valid calls. Now checks isVariadic and sets parameterCount = undefined (matching extractMethodSignature). 2. C++ bare `...` token: extractCppParameters only iterated named children, missing the unnamed `...` token in C-style variadics like log_entry(const char* fmt, ...). Added fallback scan of all children. 3. Return type stripping: All 11 language extractReturnType functions used extractSimpleTypeName() which strips generic parameters (List<User> → "List", Task<User> → "Task"). Changed to .text?.trim() to preserve full generic types needed for for-loop iterable resolution, async-await binding, and return-type inference. Also fixes PHP abstract dispatch test that matched SqlRepository instead of the interface due to ambiguous filePath.includes('Repository') filter, and adds parent-walk fallback in PHP isAbstract for extractFromNode path. * chore: remove plan and review artifacts from PR * fix: address Round 4 review findings + infrastructure improvements - Ruby: add singleton_class support for class << self methods (4 new tests) - PHP: add enum_declaration to CLASS_CONTAINER_TYPES - Dart: add mixin/extension labels to CONTAINER_TYPE_TO_LABEL - Swift: add TODO for unverifiable struct/enum node types on Node 22 - C#: add grammar version comment (0.23.1) - Ruby: fix version comment range to pin (0.23.1) - Rust/ast-helpers: add cross-reference comments for impl_item duplication - ast-helpers: document CLASS_CONTAINER_TYPES ↔ typeDeclarationNodes invariant - generic.ts: replace Array.includes with Set for O(1) dedup in addNestedBodies - Go/Python/Ruby: align isAbstract signature with 2-param interface contract - CLAUDE.md: fix malformed backtick around gitnexus:start HTML comment - parsing-processor: add per-class method extraction cache (eliminates O(N*M)) - ast-helpers: add scoped_type_identifier to impl_item resolution - call-processor: add dev-mode warnings at silent candidates[0] fallbacks - MCP context(): surface methodMetadata for Method/Function/Constructor nodes - resources.ts: update schema to list all stored Method properties * fix: singleton_class HAS_METHOD edge regression in findEnclosingClassInfo singleton_class (class << self) was added to CLASS_CONTAINER_TYPES but has no name field — its receiver `self` has node type 'self', not 'identifier'. findEnclosingClassInfo now walks up to the enclosing class/module to inherit its name, matching ruby.ts:extractOwnerName. Also fixes findEnclosingClassNode in parse-worker.ts to skip singleton_class and return the actual class/module node. Adds integration test assertions for from_habitat (class << self method): HAS_METHOD edge from Animal, isStatic=true, parameterCount=1. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ba5de0bde4
|
feat(cpp): C/C++ MethodExtractor config with pure virtual detection (#617)
* feat(cpp): C/C++ MethodExtractor config with pure virtual detection (#572) - Pure virtual (= 0) detected as isAbstract via token scanning - virtual/final/override via hasKeyword and virtual_specifier children - Access specifier visibility via backward sibling walk (public:/private:/protected:) - Pointer/reference parameter types extracted correctly - Constructor and destructor support via declaration node type - Static detection via storage_class_specifier - 16 new tests covering all acceptance criteria * fix(cpp): isVirtual infers from override/final + out-of-class resolution - isVirtual returns true for override/final methods (C++ mandates these are virtual) - Add findClassNodeByQualifiedName to parse-worker: resolves Foo::bar() back to the Foo class declaration for method extractor enrichment - Handles pointer/ref return types, constructors, destructors - Integration test for virtual/static/constructor inline methods - 233 unit+integration tests pass, 97 C++ resolver tests pass * fix(cpp): address review — deep pointers, templates, unions, trailing returns - Fix extractParamName: recursive unwrap for int** ptr → "ptr" (not "**ptr") - Fix findFunctionDeclarator: recursive unwrap for multi-level pointer chains - Template methods: generic extractor unwraps template_declaration to inner node - union_specifier: added to typeDeclarationNodes, visibility defaults to public - Trailing return type: auto foo() -> T now extracts T instead of "auto" - Fix version comment: ^0.22.4 → ^0.23.4 to match package.json - 4 new tests: double pointer params, template methods, union methods, trailing returns * fix(cpp): template method visibility + union isTypeDeclaration test extractCppVisibility now walks from the template_declaration parent when the node is wrapped by a template, restoring correct access- specifier resolution for templated class methods. Also adds missing isTypeDeclaration assertion for union_specifier and expands the template method test with explicit visibility checks. * fix(cpp): address deep gap analysis review findings - findClassNodeByQualifiedName: recursive pointer/reference declarator unwrap, fixing out-of-class linking for deep pointer return types (e.g. int** Foo::bar()) - findClassNodeByQualifiedName: recurse into namespace_definition blocks so namespace-wrapped classes resolve correctly - Suppress = delete / = default special members from extraction via delete_method_clause / default_method_clause node detection - Update known-gaps: namespace-wrapped classes, const-overload collapse - Add tree-sitter-c version comment for consistency - toBeFalsy() → toBe(undefined) for precise isVirtual assertion - Tests: = delete, = default, = 0 non-regression, operator overloads, deep pointer return types, default visibility (class vs struct), multiple access specifier sections |
||
|
|
12be2025f1
|
feat(ts,js): TypeScript/JavaScript MethodExtractor config (#588)
* feat(ts,js): MethodExtractor config for TypeScript and JavaScript (#570) Add per-language method extraction config following the established JVM and C# patterns. Shared config base mirrors the field extractor's typescript-javascript.ts pattern — TS-only node types are harmless no-ops for JS. Key features: - isAbstract for abstract class methods and interface methods - Parameter extraction with isOptional (?:, defaults) and isVariadic (...) - Decorator extraction from preceding body-level siblings - isAsync and isOverride detection - Visibility via accessibility_modifier two-pass pattern - Return type extraction unwrapping type_annotation * test(ts,js): add override, getter/setter, destructured param tests Address code review findings: - Add override method detection test - Add getter/setter extraction test - Add destructured parameter with type annotation test - Tighten constructor and private method assertions * refactor(ts,js): address code review findings - Replace O(M*N) decorator index scan with previousNamedSibling walk - Remove dead findVisibility 'modifiers' fallback (TS uses accessibility_modifier, not a modifiers wrapper) - Document call_signature/construct_signature as known gaps - Document that TS constructors are method_definition nodes - Remove unused findVisibility import * fix(ts,js): type guard before cast, add generator/computed/overload tests - Use type guard pattern (Set.has check before as-cast) in visibility extraction to ensure string is validated before narrowing - Add generator method test (*items()) — confirms extraction works - Add computed property name test ([Symbol.iterator]) — documents bracket-in-name behavior as intentional - Add class-level method overload test — verifies overload signatures + implementation are all extracted * fix(ts,js): detect #private methods as visibility 'private' ES2022 private class methods (#name) use private_property_identifier as their name node type. Detect this and return 'private' visibility instead of the default 'public'. * fix(ts,js): address review findings + close ingestion gaps - hasKeyword/findVisibility: skip name field child to prevent false positives on soft-keyword method names (e.g. `abstract()`, `static()`) - extractTsJsParameters: filter TS `this` parameter (compile-time only) - extractMethodSignature: mirror `this`-param skip in fallback path - tree-sitter queries: capture abstract_method_signature, method_signature, and private_property_identifier for TS; add private_property_identifier for JS - Remove dead childForFieldName('name') fallbacks and typeFromAnnotation fallback - Add 10+ unit tests, 4 integration tests through query pipeline * test(ts): update HAS_METHOD count for interface method_signature capture The new method_signature query now captures ILogger.log() as a Method node with a HAS_METHOD edge, increasing the expected count from 4 to 5. * fix(ts,js): address second review — async generator test, declare module gap - Add async generator method test (async *values() → isAsync: true) - Document declare module/global augmentation as known gap |
||
|
|
c72890d59d
|
feat(csharp): C# MethodExtractor config (#582)
* feat(csharp): add C# MethodExtractor config (#573) Add C# method extraction config mirroring the JVM pattern from PR #576. Wire csharpMethodConfig into the C# language provider and add 18 tests covering classes, interfaces, abstract classes, structs, records, constructors, params/out/ref/optional parameters, sealed methods, attributes, and visibility modifiers. * fix(csharp): add destructor, operator, conversion operator, and in-param support - Add destructor_declaration, operator_declaration, and conversion_operator_declaration to methodNodeTypes - Custom extractName for operators (e.g., "operator +", "implicit operator double") - Fix extractReturnType for operator declarations (use type field, not returns) - Add in modifier to parameter extraction (alongside out/ref) - Add 4 new tests: destructor, operator+, implicit conversion, in parameter * fix(csharp): add ref param test and document compound visibility limitation - Add test for ref parameter modifier (was only testing out) - Document that protected internal / private protected resolve to first modifier * feat(csharp): support compound visibilities (protected internal, private protected) - Add 'protected internal' and 'private protected' to FieldVisibility union - Detect compound modifiers in both C# method and field extractors via collectModifierTexts helper scanning adjacent modifier nodes - Add 2 tests for compound visibility detection * feat(csharp): primary constructors, virtual/override/async, primary fields Address all known limitations from review: - Primary constructor support (C# 12): add extractPrimaryConstructor to MethodExtractionConfig and extractPrimaryFields to FieldExtractionConfig. Record params become public readonly properties; class params become private captured fields. - Add isVirtual, isOverride, isAsync optional fields to MethodInfo, MethodExtractionConfig, NodeProperties, and parse-worker propagation. - Detect virtual/override/async modifiers in C# method config. - Move collectModifierTexts to shared helpers.ts (deduplicate). - Fix destructor name to ~ClassName (disambiguates from constructor). - Add expression-bodied method test. - 118 tests total across method + field extraction suites, all passing. * fix(csharp): review round 2 — annotations, record_struct, grammar pin - Fix primary constructor annotations: use [] instead of extracting class-level attributes (C# has no syntax for ctor-specific attributes) - Add record_struct_declaration to typeDeclarationNodes in both method and field extractors, CLASS_CONTAINER_TYPES, and isRecord visibility check - Pin tree-sitter-c-sharp version (^0.23.1) in params comment * fix(csharp): complete record_struct query + label mapping, sealed override test - Add record_struct_declaration capture patterns to tree-sitter-queries.ts (type definition + primary constructor) - Add record_struct_declaration → 'Struct' in CONTAINER_TYPE_TO_LABEL - Assert isOverride: true alongside isFinal in sealed override test * fix(csharp): record_struct label mismatch, add record struct + documented limitation tests - Fix record_struct_declaration query tag: @definition.struct (not @definition.record) to match CONTAINER_TYPE_TO_LABEL and prevent broken HAS_METHOD edges - Add 3 record struct tests: isTypeDeclaration, method extraction, primary constructor - Add documented limitation tests: partial method (isAbstract: false), generic type parameter stripping (name excludes <T>) * fix(csharp): remove record_struct_declaration — not a real tree-sitter node type tree-sitter-c-sharp 0.23.1 parses 'record struct' as record_declaration (absorbs the 'struct' keyword as an unnamed child token). The non-existent record_struct_declaration in queries caused TSQueryErrorNodeType, breaking ALL C# file processing. Remove from: tree-sitter-queries.ts, typeDeclarationNodes in both extractors, CLASS_CONTAINER_TYPES, and CONTAINER_TYPE_TO_LABEL. Record struct types are already handled via record_declaration. * feat(csharp): add isPartial support, filter targeted attributes, static ctor test - Add isPartial optional field to MethodInfo, MethodExtractionConfig, NodeProperties, and parse-worker propagation pipeline - Detect partial modifier in C# config — marks both declaration-only and implemented partial methods - Filter targeted attribute lists (e.g. [return: MarshalAs(...)]) in extractCSharpAnnotations — only untargeted attributes collected - Add static constructor test (isStatic: true, same name as class) - Add 3 partial method tests: declaration-only, with body, coexisting pair - Document record_struct/record_class as defensive dead code in export-detection.ts (grammar absorbs keywords into record_declaration) * fix(csharp): this param for extension methods, dedup visibility, test fixes - Handle this modifier on extension method parameters (type prefixed as 'this string', consistent with out/ref/in handling) - Deduplicate visibility logic in extractPrimaryConstructor — reuse csharpMethodConfig.extractVisibility instead of inline compound check - Fix record struct test title to reflect actual grammar behavior - Add conversion operator returnType assertion - Add extension method this parameter test * fix(csharp): primary constructor line points to param list, empty name guard - Use paramList.startPosition instead of ownerNode.startPosition for primary constructor line number (avoids methodInfoCache key collision) - Guard against empty param names from tree-sitter error recovery nodes |
||
|
|
313b13fade
|
feat(java,kotlin): MethodExtractor abstraction with per-language configs (#576) |