#2944·ast-grep

outline: Java `record_declaration` missing from `java.yml`

Author: michal-michalukCreated Sep 18, 2026Updated Sep 18, 2026

Summary

The bundled Java outline rules in crates/outline/src/default_rules/java.yml have no rule for record_declaration, so a Java file whose only type is a record produces no outline elements at all. This is not a missing grammar node and not a schema limitation: both the grammar and schemas/java_rule.json already know the kind. Only the rule data is missing.

A record is the idiomatic Java type for data carriers (Java 16+), so this makes a large share of modern Java files unmeasurable by anything built on the outline extractor.

Reproduction

Minimal failing fixture:

java
public record R(int a, int b) { }

ast-grep outline / any consumer of DEFAULT_OUTLINE_RULES returns no elements for this file. A record nested inside another type also disappears, and in that case its members are attributed to the enclosing type instead.

Evidence

1. The grammar has the node (no grammar gap)

tree-sitter-java 0.23.5 (the version ast-grep pins):

  • src/node-types.json defines record_declaration (plus record_pattern, record_pattern_body, record_pattern_component), e.g. at src/node-types.json:3007 and referenced as a member type at lines 147, 1133, 1667, 2302.
  • grammar.js:1022 defines record_declaration: $ => seq(..., 'record', ...), and grammar.js:950 already lists $.compact_constructor_declaration, // For records. inside the record's class body.

2. The schema accepts the kind (no schema gap)

ast-grep's own generated schema already lists record_declaration as a valid Java kind:

  • schemas/java_rule.json:247
  • schemas/java_rule.json:624

So the rule loader would accept a rule matching this kind today; there is simply none.

3. The bundled rules cover six kinds and no record

crates/outline/src/default_rules/java.yml (on main, byte-identical to the published ast-grep-outline 0.45.3 crate, sha256 2f82f85cf04eacc8883a02571ac90efe86bacd25458b0def05892f3e9c2ff46e) covers exactly:

rule id kind
java-interface interface_declaration
java-enum enum_declaration
java-class class_declaration
java-member-method method_declaration
java-member-constructor constructor_declaration
java-member-field field_declaration

plus two pattern-based import rules (java-import, java-static-import). No record_declaration rule exists, and the file has not been modified since the rules were added in #2739.

4. Not previously reported

A search of this repo's issues and PRs for record_declaration, java record and record outline returns nothing that requests this rule; the API search for record_declaration returns total_count: 0. No open or closed issue or PR asks for it.

Expected behaviour

A record should be an outline element, symmetric with class_declaration / enum_declaration / interface_declaration.

Proposed fix

Add a rule to java.yml, mirroring the existing rules' shape and the rec/struct precedent already used for C# (csharp-record maps record_declaration to symbolType: struct):

yaml
id: java-record
language: Java
role: item
symbolType: struct
rule:
  all:
    - kind: record_declaration
    - has:
        field: name
        pattern: $NAME
name: $NAME
isExported:
  has:
    kind: modifiers
    has:
      pattern: public

Scope note (not part of this issue): symbolType: struct is what the current model can express; there is no Record variant in crates/outline/src/model.rs. If a dedicated symbol type is wanted, that is a separate proposal.

Environment

  • ast-grep-outline 0.45.3 (latest on crates.io)
  • tree-sitter-java 0.23.5 (latest, and the version pinned by ast-grep)