Skip to content

Java

Last verified end to end: 2026-08-04 (query_code schema version 1).

For exact inbound and outbound symbol edges, proof tiers, and adapter-specific caveats, see Reference Traversal.

Java normalizes methods, constructors, annotations, object creation, member calls, imports, assignments, exceptions, and control flow. The fixture includes two post receivers so receiver filtering proves a real exclusion.

package app;
import java.io.IOException;
@interface Route {}
class Response {}
class Client {
Response post(String path) { return new Response(); }
}
class Api {
@Route
Api() {}
@Route
Response save(Client client, Client backup, String path) {
backup.post(path);
try {
if (path.isEmpty()) {
throw new IllegalArgumentException();
}
while (path.startsWith("/")) {
return client.post(path);
}
return new Response();
} catch (RuntimeException error) {
throw error;
}
}
}
class Batch {
void drain(java.util.List<String> paths) {
for (String path : paths) {
path.trim();
}
}
}

callee: "post" alone finds both calls. receiver: "client", the positional capture, and inside select only the return-path call in Api.save.

(inside
(method :name "save")
(language java
(call :callee "post" :receiver "client" :args [(capture "path")])) )
{
"languages": ["java"],
"match": {
"kind": "call",
"callee": {"name": "post"},
"receiver": {"name": "client"},
"args": [{"capture": "path"}]
},
"inside": {"kind": "method", "name": "save"}
}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "call",
"start_line": 25,
"end_line": 25,
"text": "client.post(path)",
"captures": [{"name": "path", "text": "path", "start_line": 25}],
"enclosing_symbol": "app.Api.save"
}
],
"truncated": false
}

Java receiver traversal uses shared semantic value and heap evidence together with bounded Java type and definition resolution. This query starts from the exact client.post(path) structural match and returns the typed Client receiver with an explicit analysis outcome.

(receiver-targets
(inside
(method :name "save")
(language java
(call :callee "post" :receiver "client"))))
{
"languages": ["java"],
"match": {
"kind": "call",
"callee": {"name": "post"},
"receiver": {"name": "client"}
},
"inside": {"kind": "method", "name": "save"},
"steps": [{"op": "receiver_targets"}]
}
{
"results": [
{
"analysis_kind": "receiver_targets",
"input_kind": "identifier",
"language": "java",
"outcome": "precise",
"path": "java/App.java",
"provenance": [
{
"seed": {
"end_line": 25,
"kind": "call",
"path": "java/App.java",
"result_type": "structural_match",
"start_line": 25
},
"steps": [
{
"op": "receiver_targets",
"result": {
"analysis_kind": "receiver_targets",
"outcome": "precise",
"path": "java/App.java",
"range": {
"end_column": 30,
"end_line": 25,
"start_column": 24,
"start_line": 25
},
"result_type": "receiver_analysis"
}
}
]
}
],
"range": {
"end_column": 30,
"end_line": 25,
"start_column": 24,
"start_line": 25
},
"result_type": "receiver_analysis",
"site_ast_id": "3bc1940c77bd67811e353b90dd15b4854c289cddfe56924df27c0f28f4b511de",
"site_id": "092f93072ecc0fa7907f049ba694926e3a98b4520a050f854ae369350878c71c",
"text": "client",
"values": [
{
"declaration": {
"end_line": 11,
"fq_name": "app.Client",
"kind": "class",
"language": "java",
"path": "java/App.java",
"signature": "class Client {",
"start_line": 9
},
"receiver_value_kind": "instance_type"
}
]
}
],
"truncated": false
}

The companion points_to and member_targets steps use the same receiver-query path. Every analyzed input returns precise, ambiguous, unknown, unsupported, or exceeded_budget; a zero-result is not substituted for uncertainty.

Java annotations use the normalized decorators role. A constructor remains distinct from an ordinary method.

(constructor :name "Api" :decorators [(decorator :name "Route" :capture "annotation")])
{
"match": {
"kind": "constructor",
"name": "Api",
"decorators": [
{"kind": "decorator", "name": "Route", "capture": "annotation"}
]
}
}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "constructor",
"start_line": 14,
"end_line": 15,
"text": "@Route…",
"captures": [
{"name": "annotation", "text": "@Route", "start_line": 14}
],
"enclosing_symbol": "app.Api.Api"
}
],
"truncated": false
}

has searches descendants, so these queries select only the catch, conditional, and loop that contain the requested statement shape.

(catch (has (throw :capture "rethrown")))
{"match":{"kind":"catch","has":{"kind":"throw","capture":"rethrown"}}}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "catch",
"start_line": 28,
"end_line": 30,
"text": "catch (RuntimeException error) {…",
"captures": [
{"name": "rethrown", "text": "throw error;", "start_line": 29}
],
"enclosing_symbol": "app.Api.save"
}
],
"truncated": false
}
(if (has (throw :capture "failure")))
{"match":{"kind":"if","has":{"kind":"throw","capture":"failure"}}}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "if",
"start_line": 21,
"end_line": 23,
"text": "if (path.isEmpty()) {…",
"captures": [
{
"name": "failure",
"text": "throw new IllegalArgumentException();",
"start_line": 22
}
],
"enclosing_symbol": "app.Api.save"
}
],
"truncated": false
}
(loop (has (return :capture "exit")))
{"match":{"kind":"loop","has":{"kind":"return","capture":"exit"}}}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "while_loop",
"start_line": 24,
"end_line": 26,
"text": "while (path.startsWith(\"/\")) {…",
"captures": [
{
"name": "exit",
"text": "return client.post(path);",
"start_line": 25
}
],
"enclosing_symbol": "app.Api.save"
}
],
"truncated": false
}

loop is subtype-aware: the result above reports its refined kind while_loop. Query while_loop directly for condition-controlled loops, or for_loop for the for-each family (Java’s enhanced for; the classic counting for stays plain loop).

(while_loop (has (return :capture "exit")))
{"match":{"kind":"while_loop","has":{"kind":"return","capture":"exit"}}}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "while_loop",
"start_line": 24,
"end_line": 26,
"text": "while (path.startsWith(\"/\")) {…",
"captures": [
{
"name": "exit",
"text": "return client.post(path);",
"start_line": 25
}
],
"enclosing_symbol": "app.Api.save"
}
],
"truncated": false
}
(for_loop (has (call :callee (name "trim") :capture "work")))
{"match":{"kind":"for_loop","has":{"kind":"call","callee":{"name":"trim"},"capture":"work"}}}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "for_loop",
"start_line": 36,
"end_line": 38,
"text": "for (String path : paths) {…",
"captures": [
{
"name": "work",
"text": "path.trim()",
"start_line": 37
}
],
"enclosing_symbol": "app.Batch.drain"
}
],
"truncated": false
}

block matches a statement list that opens a scope of its own: a method body, a bare block, the body of a loop or conditional, and a switch body. Class bodies are member lists, not statement lists, so they never match. Combine it with inside to reach one specific scope.

(inside (for_loop) (language java (block (has (call :callee (name "trim") :capture "work")))))
{
"languages": ["java"],
"match": {
"kind": "block",
"has": {"kind": "call", "callee": {"name": "trim"}, "capture": "work"}
},
"inside": {"kind": "for_loop"}
}
{
"results": [
{
"result_type": "structural_match",
"path": "java/App.java",
"language": "java",
"kind": "block",
"start_line": 36,
"end_line": 38,
"text": "{…",
"captures": [
{
"name": "work",
"text": "path.trim()",
"start_line": 37
}
],
"enclosing_symbol": "app.Batch.drain"
}
],
"truncated": false
}

Java has positional arguments but no keyword-argument syntax. Asking for kwargs produces a capability diagnostic and no pretend match.

(language java (call :callee "post" :kwargs [(path (name "path"))]))
{
"languages": ["java"],
"match": {
"kind": "call",
"callee": {"name": "post"},
"kwargs": {"path": {"name": "path"}}
}
}
{
"results": [],
"truncated": false,
"diagnostics": [
{
"code": "unsupported_structural_feature",
"impact": "incomplete",
"language": "java",
"message": "structural adapter for java does not support role(s): kwargs"
}
]
}

Receiver names are syntactic. receiver: "client" does not prove that the variable has type Client; use symbol and usage tools when identity matters.

class QueryRoot {
void rootMember() {}
}
class QueryLeaf extends QueryRoot {
void leafMember() {}
}
(supertypes (enclosing-decl (language java (class :name "QueryLeaf"))))
{"languages":["java"],"match":{"kind":"class","name":"QueryLeaf"},"steps":[{"op":"enclosing_decl"},{"op":"supertypes"}]}
{
"results": [
{
"end_line": 3,
"fq_name": "QueryRoot",
"kind": "class",
"language": "java",
"path": "java/QueryHierarchy.java",
"provenance": [
{
"seed": {
"end_line": 7,
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "structural_match",
"start_line": 5
},
"steps": [
{
"op": "enclosing_decl",
"result": {
"end_line": 7,
"fq_name": "QueryLeaf",
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 5
}
},
{
"op": "supertypes",
"result": {
"end_line": 3,
"fq_name": "QueryRoot",
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 1
}
}
]
}
],
"result_type": "declaration",
"signature": "class QueryRoot {",
"start_line": 1
}
],
"truncated": false
}
(owner (members (subtypes :transitive true (enclosing-decl (language java (class :name "QueryRoot"))))))
{"languages":["java"],"match":{"kind":"class","name":"QueryRoot"},"steps":[{"op":"enclosing_decl"},{"op":"subtypes","transitive":true},{"op":"members"},{"op":"owner"}]}
{
"results": [
{
"end_line": 7,
"fq_name": "QueryLeaf",
"kind": "class",
"language": "java",
"path": "java/QueryHierarchy.java",
"provenance": [
{
"seed": {
"end_line": 3,
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "structural_match",
"start_line": 1
},
"steps": [
{
"op": "enclosing_decl",
"result": {
"end_line": 3,
"fq_name": "QueryRoot",
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 1
}
},
{
"op": "subtypes",
"result": {
"end_line": 7,
"fq_name": "QueryLeaf",
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 5
}
},
{
"op": "members",
"result": {
"end_line": 6,
"fq_name": "QueryLeaf.leafMember",
"kind": "function",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 6
}
},
{
"op": "owner",
"result": {
"end_line": 7,
"fq_name": "QueryLeaf",
"kind": "class",
"path": "java/QueryHierarchy.java",
"result_type": "declaration",
"start_line": 5
}
}
]
}
],
"result_type": "declaration",
"signature": "class QueryLeaf extends QueryRoot {",
"start_line": 5
}
],
"truncated": false
}