Skip to content

Add Java - #6

Merged
lightningpixel merged 1 commit into
mainfrom
feat/java-support
Aug 9, 2026
Merged

Add Java#6
lightningpixel merged 1 commit into
mainfrom
feat/java-support

Conversation

@lightningpixel

Copy link
Copy Markdown
Owner

Follows the six steps in AGENTS.md: a languages.ts entry, the grammar in copy-grammars.mjs, queries/java.scm, local-scope node types and an export rule in extract.ts, tests, and the family field.

Indexes classes, records, interfaces, enums, annotation types, methods, constructors and fields.

Two things Java forced

Visibility is stated per member. inheritExportedFromContainer exists because a method of an exported TypeScript class carries no export keyword of its own. Applied to Java it marks private int shut() as part of the public surface, which contradicts the source. Languages that state member visibility now opt out of that inheritance.

Calls are tagged apart by receiver, as in typescript.scm(method_invocation object: (_) …) versus (method_invocation !object …). Without it every list.get(…) would reach any method named get.

Measured on real code, not fixtures

google/gson — 264 files, 5 009 symbols, 22 135 call sites:

share
resolved to an edge 18%
refused as ambiguous 32%
into the JDK 49%

The refusals are the rule working, not a defect. Java reuses get, add, create, value, append across unrelated classes, and x.get(…) cannot be attributed without the type of x. I checked whether collapsing overloads would help: only 5% of ambiguous sites had all candidates in one class, so it would not.

Compare Modly (TypeScript + Python): 1 546 edges against 47 ambiguous sites.

So Java is weaker than the other languages here. map, show and find behave exactly as they do everywhere — the symbol map, the ranked tree, one symbol's exact source. who-calls and calls see roughly a third of what they see in a TypeScript project, and ranking, which reads the call graph, is correspondingly flatter. The README states this beside the language list rather than leaving it to be discovered.

This is worth a decision rather than a merge on autopilot: it is honest and useful, but it is not the same quality of support as TypeScript, and shipping it sets an expectation.

Verification

  • npm run build, npx tsc --noEmit, npm test — 375 tests pass
  • Five tests written first and watched fail with no language for src/Service.java; the visibility one then failed a second time for a real reason — container inheritance overriding private — which is what produced the opt-out above
  • Indexed google/gson end to end
  • Packed size 647 kB → 703 kB (Java's grammar is 405 kB; C# and C++ are 4.9 and 5.1 MB, a different conversation)

Follows the six steps in AGENTS.md: a languages.ts entry, the grammar in
copy-grammars.mjs, queries/java.scm, local-scope node types and an export rule
in extract.ts, tests, and the family field.

Two things Java forced that the existing languages did not.

Visibility is stated per member, so the enclosing type must not speak for it.
`inheritExportedFromContainer` exists because a method of an exported
TypeScript class carries no export keyword of its own; applying it to Java
would mark `private int shut()` as part of the public surface. Languages that
state member visibility now opt out.

Method calls are tagged apart by receiver, as in typescript.scm. Without it
every `list.get(…)` in a project would reach any method named get.

Measured on google/gson — 264 files, 5009 symbols, real code rather than
fixtures: 18% of call sites resolved, 32% refused as ambiguous, 49% into the
JDK. The refusals are the rule working as intended, not a defect: Java reuses
get, add, create and value across unrelated classes, and only 5% of the
ambiguous sites were overloads of a single method, so collapsing overloads
would not recover them. `x.get(…)` needs the type of x, which a syntactic
resolver does not have.

That makes Java weaker than the other languages for who-calls and calls, and
flatter for ranking, while map, show and find are unaffected. The README says
so beside the language list rather than leaving it to be discovered.

Packed size 647 kB -> 703 kB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lightningpixel
lightningpixel merged commit ee0b3d2 into main Aug 9, 2026
11 checks passed
@lightningpixel
lightningpixel deleted the feat/java-support branch August 9, 2026 13:12
@lightningpixel lightningpixel mentioned this pull request Aug 9, 2026
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