Skip to content

feat(neo4j): derive code onto declarations, matching python and java - #139

Merged
rahlk merged 1 commit into
mainfrom
feat/graph-code-projection-v2
Sep 2, 2026
Merged

feat(neo4j): derive code onto declarations, matching python and java#139
rahlk merged 1 commit into
mainfrom
feat/graph-code-projection-v2

Conversation

@rahlk

@rahlk rahlk commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Replaces #136 (same commit, cherry-picked onto main after the stack below it merged).

The gap

TypeScript source text was unreachable from the graph: :TSCallable had no code, and
:TSModule had no source to slice from — nodes carried start_line/end_line, not the
span.bytes the tree uses. Neither route worked. python and java hand a consumer code directly.

The JSON model was never the disagreement

JSON Neo4j code
python module source once + span.bytes; no per-callable code derived at projection
typescript module source once + span.bytes; no per-callable code was missing
java code stored per callable carried through

python and TypeScript already agree on the JSON model. python then completes the contract on the
graph side (neo4j/project.py::_span_code):

"A declaration's text: the owning module's source sliced by the node's utf-8 byte span. Schema
v2 stores source once per module, so the graph's code property … is derived here at projection
time (#104)."

TypeScript stopped short of that step. This adds it — no JSON change, no text stored twice.

Details matched deliberately

  • spanCode slices a Buffer, not the string. span.bytes are UTF-8 byte offsets and JS
    strings are UTF-16, so source.slice() would cut multi-byte characters.
  • ts_code_fts, a fulltext index over TSCallable.code, mirroring python's py_code_fts.
    Text on a node that cannot be searched is half a feature.
  • code is declared on every label that receives itTSCallable plus the five type labels,
    since typeProps is shared. python declares it only on PyClass/PyCallable; declaring it where
    it is actually emitted keeps the conformance gate meaningful.

Verification

Live graph, sample-app: 41 of 42 callables carry code (the holdout is a bodiless
declaration). Sample value:

"Get" → "function Get(path: string): MethodDecorator {\n  return () =>…"

WHERE c.code CONTAINS "..." now works. Suite: 240 pass, 0 fail; gen:schema clean.

Related

TypeScript source text was unreachable from the graph. :TSCallable carried no
`code`, and :TSModule carried no `source` to slice from -- nodes had only
start_line/end_line, not the `span.bytes` the tree uses. So neither route
worked, while python and java hand a consumer `code` directly.

The JSON model was never the disagreement: python and typescript both store a
module's text ONCE and address nodes into it by UTF-8 byte span, with no
per-callable `code` field. Python then derives `code` at projection time
(neo4j/project.py::_span_code, "schema v2 stores source once per module, so the
graph's `code` property ... is derived here"). TypeScript simply stopped short
of that step. This adds it.

`spanCode` slices a Buffer, not the string: `span.bytes` are UTF-8 byte offsets
and JS strings are UTF-16, so string slicing would cut multi-byte characters --
the same trap that had to be fixed in artifact text capture.

Also adds `ts_code_fts`, a fulltext index over TSCallable.code, mirroring
python's `py_code_fts`. Text on a node that cannot be searched is only half the
feature.

`code` is declared on every label that receives it -- TSCallable plus the five
type labels, since typeProps is shared -- rather than only the two python
declares, so the conformance gate stays honest.

Verified on a live graph: 41 of 42 callables carry sliced source (the one
without is a bodiless declaration), e.g. Get -> "function Get(path: string):
MethodDecorator {\n  return () =>...". Full suite with containers: 237 pass.

Java's JSON stores `code` per callable instead of slicing; filed as
codellm-devkit/codeanalyzer-java#215.
@rahlk
rahlk merged commit 868844e into main Sep 2, 2026
1 check passed
@rahlk
rahlk deleted the feat/graph-code-projection-v2 branch September 2, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant