Skip to content

feat(codegen)!: centralize typed context mechanics - #299

Merged
tinovyatkin merged 1 commit into
mainfrom
codex/issue-276-context-runtime-api
Aug 4, 2026
Merged

feat(codegen)!: centralize typed context mechanics#299
tinovyatkin merged 1 commit into
mainfrom
codex/issue-276-context-runtime-api

Conversation

@tinovyatkin

@tinovyatkin tinovyatkin commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Closes #276.

Summary

  • Move grammar-independent typed parser context storage, constructors,
    conversions, common accessors, and invocation-state display behind the
    doc-hidden runtime __antlr4_rust_context! support macro.
  • Reduce generated context declarations to rule identity, context kind,
    optional grammar attributes, and collision-safe method names while preserving
    the existing public stored, active, recovered, validated, listener, visitor,
    and downcast behavior.
  • Stop emitting empty __RuleAttrsN payloads and attribute lookups for rules
    without generated attributes.
  • Increment the generated-code API to revision 4, retain revisions 1 through 3
    while their runtime surfaces remain available, and regenerate checked-in
    recognizers, snapshots, hashes, and compatibility documentation.

Measured impact

ANTLRv4 generated frontend Baseline Current Change
Lines 26,446 14,118 -46.62%
Bytes 3,966,951 3,511,229 -11.49%

Seven interleaved warm package-check rebuilds were effectively unchanged:
1.561 s baseline versus 1.571 s current. The release antlr4-rust-gen binary
decreased from 11,632,512 to 11,617,920 bytes, a 14,592-byte (0.125%) reduction.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
  • cargo test --locked --workspace --all-features
  • tools/grammar-frontend/update-stage0.sh --check
  • tools/rust-syntax/update-generated.sh --check
  • Kotlin parse-tree parity: 9/9 fixtures
  • JavaScript token and parse-tree parity: 6/6 fixtures
  • TypeScript token and parse-tree parity: 5/5 fixtures
  • Upstream ANTLR runtime testsuite: 357 passed, 0 failed, 0 skipped

Summary by CodeRabbit

  • New Features
    • Added shared runtime support for generated parser contexts, including typed accessors, context validation, attributes, display formatting, and state handling.
    • Added compatibility support for generated code API revision 4 while retaining revisions 1–3.
  • Improvements
    • Generated parsers no longer create empty attribute structures for rules without attributes.
    • Updated generated-parser compatibility and API validation coverage.

Move generated typed parser context storage, constructors, conversions, common accessors, and invocation-state display behind a doc-hidden runtime macro. Generated contexts now declare only their rule identity, optional attributes, context kind, and collision-safe method names.

Do not emit empty per-rule attribute payloads or attribute lookups for attrless rules. Preserve the existing stored, active, recovered, validated, listener, visitor, and downcast surfaces through the shared implementation.

Bump the generated-code API to revision 4 because new generated parsers require the runtime support macro. Keep revisions 1 through 3 accepted while their runtime surfaces remain available, and regenerate all checked-in recognizers, compatibility snapshots, and documentation.

For the checked-in ANTLRv4 frontend, generated source falls from 26,446 to 14,118 lines and from 3,966,951 to 3,511,229 bytes. Seven warm package checks remain effectively unchanged at 1.561s baseline versus 1.571s current; the release generator binary is 14,592 bytes smaller.
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Copy/Paste Detection

Found 14 duplication(s) across 12 changed non-generated Rust file(s) (threshold: 100 tokens).

Show duplications

Found a 26 line (142 tokens) duplication in the following files:

  • Starting at line 4028 of crates/antlr-rust-codegen/src/generator/tests.rs
  • Starting at line 4251 of crates/antlr-rust-codegen/src/generator/tests.rs
    atn.set_end_state(1, 4).expect("block end state");
    atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
        .expect("transition");
    atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
        .expect("transition");
    atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
        .expect("transition");
    atn.add_transition(
        2,
        ParserTransitionSpec::Atom {
            target: 4,
            label: 1,
        },
    )
    .expect("transition");
    atn.add_transition(
        3,
        ParserTransitionSpec::Atom {
            target: 4,
            label: 2,
        },
    )
    .expect("transition");
    atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
        .expect("transition");
    atn.add_decision_state(1).expect("decision state");
```rust

---

Found a 23 line (139 tokens) duplication in the following files:
* Starting at line 1021 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
* Starting at line 1080 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs

```rust
         ID: [a-z]+;\n",
    )
    .expect("delegate grammar should be writable");

    let output = run_antlr4_rust_gen(&[
        root.as_os_str(),
        OsStr::new("-I"),
        temp.path().as_os_str(),
        OsStr::new("--actions"),
        OsStr::new("embedded"),
        OsStr::new("--sem-unknown"),
        OsStr::new("error"),
        OsStr::new("--require-full-semantics"),
        OsStr::new("--out-dir"),
        out.as_os_str(),
    ]);
    assert!(
        output.status.success(),
        "stdout: {}\nstderr: {}",
        utf8(&output.stdout),
        utf8(&output.stderr)
    );
    let parser = fs::read_to_string(out.join("root_parser.rs")).expect("parser should be emitted");

Found a 22 line (132 tokens) duplication in the following files:

  • Starting at line 965 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
  • Starting at line 655 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/semantics.rs
        "parser grammar Delegate;\ndelegated: {isTypeName()}? ID;\n",
    )
    .expect("delegate grammar should be writable");
    fs::write(&tokens, "lexer grammar Tokens;\nID: [a-z]+;\n")
        .expect("token grammar should be writable");

    let output = run_antlr4_rust_gen(&[
        root.as_os_str(),
        tokens.as_os_str(),
        OsStr::new("-I"),
        temp.path().as_os_str(),
        OsStr::new("--out-dir"),
        out.as_os_str(),
    ]);
    assert!(
        output.status.success(),
        "stdout: {}\nstderr: {}",
        utf8(&output.stdout),
        utf8(&output.stderr)
    );
    let parser = fs::read_to_string(out.join("root.rs")).expect("parser should be emitted");
    assert!(parser.contains("pub trait RootHooks"), "{parser}");
```rust

---

Found a 25 line (115 tokens) duplication in the following files:
* Starting at line 3999 of crates/antlr-rust-codegen/src/generator/tests.rs
* Starting at line 4209 of crates/antlr-rust-codegen/src/generator/tests.rs

```rust
        atn.add_state(AtnStateKind::BlockStart, Some(0))
            .expect("state")
            .index(),
        1
    );
    assert_eq!(
        atn.add_state(AtnStateKind::Basic, Some(0))
            .expect("state")
            .index(),
        2
    );
    assert_eq!(
        atn.add_state(AtnStateKind::Basic, Some(0))
            .expect("state")
            .index(),
        3
    );
    assert_eq!(
        atn.add_state(AtnStateKind::BlockEnd, Some(0))
            .expect("state")
            .index(),
        4
    );
    assert_eq!(
        atn.add_state(AtnStateKind::RuleStop, Some(0))

Found a 22 line (112 tokens) duplication in the following files:

  • Starting at line 4126 of crates/antlr-rust-codegen/src/generator/tests.rs
  • Starting at line 4200 of crates/antlr-rust-codegen/src/generator/tests.rs
fn plus_loop_atn() -> ParserAtn {
    let mut atn = ParserAtnBuilder::new(2);
    assert_eq!(
        atn.add_state(AtnStateKind::RuleStart, Some(0))
            .expect("state")
            .index(),
        0
    );
    assert_eq!(
        atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
            .expect("state")
            .index(),
        1
    );
    assert_eq!(
        atn.add_state(AtnStateKind::Basic, Some(0))
            .expect("state")
            .index(),
        2
    );
    assert_eq!(
        atn.add_state(AtnStateKind::BlockEnd, Some(0))
```rust

---

Found a 27 line (110 tokens) duplication in the following files:
* Starting at line 3353 of crates/antlr-rust-codegen/src/generator/tests.rs
* Starting at line 3465 of crates/antlr-rust-codegen/src/generator/tests.rs

```rust
            decision: 0,
            alts: (1, 2),
            track_alt_number: false,
            allow_semantic_context: true,
            force_context: false,
            plus_loop: false,
            fast_path: None,
            body: &body,
        },
        0,
        GeneratedStepRenderContext {
            current_rule_index: 0,
            embedded: None,
            portable_locals: None,
            decision_routing: DecisionRoutingRender::default(),
            inline_action_statements: &BTreeMap::new(),
            track_alt_numbers: false,
            track_context_alt_numbers: false,
            direct_generated_rule_calls: &[],
            atn_preferred_rule_calls: &[],
            adaptive_atn_preferred_rule_slots: &[],
            adaptive_atn_probe_rule_slots: &[],
        },
    );

    // The whole rendered star-loop captures the leading-predicate-to-exit-alt filtering.
    insta::assert_snapshot!(

Found a 20 line (107 tokens) duplication in the following files:

  • Starting at line 1162 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
  • Starting at line 1208 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
    .expect("type-position grammar should be writable");

    let output = run_antlr4_rust_gen(&[
        grammar.as_os_str(),
        OsStr::new("--actions"),
        OsStr::new("embedded"),
        OsStr::new("--sem-unknown"),
        OsStr::new("error"),
        OsStr::new("--require-full-semantics"),
        OsStr::new("--out-dir"),
        out.as_os_str(),
    ]);
    assert!(
        output.status.success(),
        "stdout: {}\nstderr: {}",
        utf8(&output.stdout),
        utf8(&output.stderr)
    );
    let parser =
        fs::read_to_string(out.join("type_position_parser.rs")).expect("parser should be emitted");
```rust

---

Found a 18 line (106 tokens) duplication in the following files:
* Starting at line 243 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
* Starting at line 13 of crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/semantics.rs

```rust
        fixtures.join("AliasCollision.g4").as_os_str(),
        OsStr::new("--actions"),
        OsStr::new("embedded"),
        OsStr::new("--sem-unknown"),
        OsStr::new("error"),
        OsStr::new("--require-full-semantics"),
        OsStr::new("--out-dir"),
        out.as_os_str(),
    ]);
    assert!(
        output.status.success(),
        "stdout: {}\nstderr: {}",
        utf8(&output.stdout),
        utf8(&output.stderr)
    );

    let manifest =
        fs::read_to_string(out.join("semantics.json")).expect("manifest should be emitted");

Found a 17 line (105 tokens) duplication in the following files:

  • Starting at line 168 of crates/antlr-rust-runtime/src/generated.rs
  • Starting at line 265 of crates/antlr-rust-runtime/src/generated.rs
            fn __from_node_with_invocation_states(
                node: $crate::RuleNodeView<'a>,
                invocation_states: Option<Vec<isize>>,
            ) -> Self {
                $(
                    let __default = <$attrs>::default();
                    let __attrs = node.generated_attrs::<$attrs>().unwrap_or(&__default);
                )?
                Self {
                    __node: __GeneratedRuleContext::Stored(node),
                    __invocation_states: invocation_states,
                    __state: std::marker::PhantomData,
                    $(
                        $($field: __attrs.$field.clone(),)+
                    )?
                }
            }
```rust

---

Found a 25 line (104 tokens) duplication in the following files:
* Starting at line 3093 of crates/antlr-rust-codegen/src/generator/tests.rs
* Starting at line 3260 of crates/antlr-rust-codegen/src/generator/tests.rs

```rust
            state: 1,
            decision: 0,
            track_alt_number: false,
            allow_semantic_context: false,
            force_context: false,
            fast_path: None,
            alts: &alts,
        },
        0,
        GeneratedStepRenderContext {
            current_rule_index: 0,
            embedded: None,
            portable_locals: None,
            decision_routing: DecisionRoutingRender::default(),
            inline_action_statements: &BTreeMap::new(),
            track_alt_numbers: false,
            track_context_alt_numbers: false,
            direct_generated_rule_calls: &[],
            atn_preferred_rule_calls: &[],
            adaptive_atn_preferred_rule_slots: &[],
            adaptive_atn_probe_rule_slots: &[],
        },
    );

    assert!(rendered.contains("ll1_decision_prediction(atn(), 1)"));

Found a 28 line (102 tokens) duplication in the following files:

  • Starting at line 3146 of crates/antlr-rust-codegen/src/generator/tests.rs
  • Starting at line 3306 of crates/antlr-rust-codegen/src/generator/tests.rs
            state: 1,
            decision: 0,
            track_alt_number: false,
            allow_semantic_context: true,
            force_context: false,
            fast_path: None,
            alts: &alts,
        },
        0,
        GeneratedStepRenderContext {
            current_rule_index: 0,
            embedded: None,
            portable_locals: None,
            decision_routing: DecisionRoutingRender::default(),
            inline_action_statements: &BTreeMap::new(),
            track_alt_numbers: false,
            track_context_alt_numbers: false,
            direct_generated_rule_calls: &[],
            atn_preferred_rule_calls: &[],
            adaptive_atn_preferred_rule_slots: &[],
            adaptive_atn_probe_rule_slots: &[],
        },
    );

    // One decision renders into a fresh String; snapshot the whole emitted control flow (the
    // semantic-context gate, both predicate probes, the alt rewrite, the no-viable fallback)
    // instead of six positive probes plus one negative guard.
    insta::assert_snapshot!(
```rust

---

Found a 16 line (101 tokens) duplication in the following files:
* Starting at line 4099 of crates/antlr-rust-codegen/src/generator/tests.rs
* Starting at line 4251 of crates/antlr-rust-codegen/src/generator/tests.rs

```rust
    atn.set_loop_back_state(3, 4).expect("loop back state");
    atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
        .expect("transition");
    atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
        .expect("transition");
    atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
        .expect("transition");
    atn.add_transition(
        2,
        ParserTransitionSpec::Atom {
            target: 4,
            label: 1,
        },
    )
    .expect("transition");
    atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })

Found a 19 line (100 tokens) duplication in the following files:

  • Starting at line 911 of crates/antlr-rust-codegen/src/parser/surface/accessors.rs
  • Starting at line 981 of crates/antlr-rust-codegen/src/parser/surface/accessors.rs
        );
        render_repeated_accessor_validation(
            &mut rendered.validation,
            method,
            view_name,
            &label.source_name,
            label.cardinality.min,
            validation_error_name,
        );
        return;
    }
    let lookup = match label.selector {
        ContextLabelSelector::Nth(occurrence) => format!(".nth({occurrence})"),
        ContextLabelSelector::LastAfter(skip) => format!(".skip({skip}).last()"),
        ContextLabelSelector::AllAfter(_) => unreachable!("handled above"),
    };
    if label.cardinality.is_required_single() {
        let _ = writeln!(
            rendered.recovered,
```rust

---

Found a 20 line (100 tokens) duplication in the following files:
* Starting at line 15 of crates/antlr-rust-codegen/src/parser/surface/names.rs
* Starting at line 346 of crates/antlr-rust-codegen/src/parser/surface/support_abi.rs

```rust
    for (rule_index, rule) in model.rules.iter().enumerate() {
        if !rule.has_attrs() {
            continue;
        }
        let struct_name = embedded::attrs_struct_name(rule_index);
        let mut fields = String::new();
        for attr in &rule.attrs {
            let _ = writeln!(
                fields,
                "    pub {}: {},",
                embedded::escape_keyword(&attr.name),
                attr.ty
            );
        }
        let _ = writeln!(
            out.attrs_structs,
            "#[derive(Clone, Debug, Default)]\n#[allow(non_snake_case, dead_code)]\npub struct {struct_name} {{\n{fields}}}\n"
        );
    }
    out.module_items.push_str(EMBEDDED_INPUT_FACADE);

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9c4b4a8e-4877-4784-86b0-c5229723faf7

📥 Commits

Reviewing files that changed from the base of the PR and between 360db15 and 03950de.

⛔ Files ignored due to path filters (47)
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__generated_module_file_header.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_branch_hazard_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_branch_rival_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_calc_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_closed_repeat_prefix_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_direct_optional_in_shared_block_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_exhaustive_prefix_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_grouped_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_inner_choice_arity_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_merged_repeats_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_merged_rivals_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_mixed_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_mixed_repetition_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_mixed_repetition_followed_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_mixed_unbounded_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_nested_exhaustive_prefix_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_nested_group_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_optional_prefix_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_overlapping_group_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_path_restricted_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_prefixed_mixed_repetition_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_shadowed_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__multi_alternative_label_shared_optional_block_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_e_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_grouped_tokens.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_latest_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_many_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_reserved_direct_terminals.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_accessors_s_context.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/src/generator/snapshots/antlr_rust_codegen__generator__tests__typed_context_runtime_support_declarations.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__cli__generated_codegen_api_checks.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__cli__generated_codegen_api_mismatch_diagnostic.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__compatibility__antlr4rust_compat_generated_surface.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__compatibility__antlr4rust_unrelated_context_surface.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__parser__inlined_token_accessors_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__configured_mutual_entry_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__configured_precedence_entry_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__inferred_mutual_entries_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__pruned_unreachable_rule_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__recursive_eof_entry_component_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/snapshots/antlr4_rust_gen_cli__transforms__unreachable_rule_default_generated_api.snap is excluded by !**/*.snap
  • crates/antlr-rust-g4-parser/src/generated/antlr_v4_lexer.rs is excluded by !**/generated/**
  • crates/antlr-rust-g4-parser/src/generated/antlr_v4_parser.rs is excluded by !**/generated/**
  • crates/antlr-rust-rs-parser/src/generated/rust_lexer.rs is excluded by !**/generated/**
  • crates/antlr-rust-rs-parser/src/generated/rust_parser.rs is excluded by !**/generated/**
  • crates/antlr-rust-runtime/src/xpath/generated/x_path_lexer.rs is excluded by !**/generated/**
  • docs/migration.md is excluded by !**/docs/**
📒 Files selected for processing (14)
  • README.md
  • crates/antlr-rust-codegen/src/generator/tests.rs
  • crates/antlr-rust-codegen/src/parser/surface/accessors.rs
  • crates/antlr-rust-codegen/src/parser/surface/contexts.rs
  • crates/antlr-rust-codegen/src/parser/surface/names.rs
  • crates/antlr-rust-codegen/src/parser/surface/support_abi.rs
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/cli.rs
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/compatibility.rs
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/semantics.rs
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/support.rs
  • crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/typed_tree.rs
  • crates/antlr-rust-runtime/src/generated.rs
  • crates/antlr-rust-runtime/src/lib.rs
  • third_party/antlr-v4-grammar/self-hosted.sha256
💤 Files with no reviewable changes (1)
  • crates/antlr-rust-codegen/src/parser/surface/accessors.rs

📝 Walkthrough

Walkthrough

Generated parser contexts now use a new exported runtime macro, __antlr4_rust_context!, replacing hand-generated context structs, constructors, common accessors, and Display implementations. The generated-code API revision increases from 3 to 4. Codegen tests, CLI compatibility fixtures, documentation, and checksums are updated accordingly.

Changes

Runtime context macro consolidation

Layer / File(s) Summary
Runtime context macro and API revision
crates/antlr-rust-runtime/src/generated.rs, crates/antlr-rust-runtime/src/lib.rs
Adds __antlr4_rust_context! macro generating typed stored/active/validated context structs with conversions, accessors, and Display. Bumps __ANTLR4_RUST_CODEGEN_API from 3 to 4 and updates the compatibility macro to accept revision 4.
Codegen surface uses runtime macro
crates/antlr-rust-codegen/src/parser/surface/contexts.rs, .../accessors.rs, .../names.rs, .../support_abi.rs
Replaces bespoke context structs, constructors, and Display code with macro invocations using exact/any context-kind matching. Removes render_context_common_accessors. Skips attribute-struct generation for rules without attributes.
Codegen unit tests updated for macro-based contexts
crates/antlr-rust-codegen/src/generator/tests.rs
Adds helpers to extract macro-based context implementations/declarations and updates assertions for invocation-state handling, runtime-generated attributes, and removed legacy downcast_ref/constructor paths.
CLI integration tests and compatibility fixtures
crates/antlr-rust-codegen/tests/antlr4_rust_gen_cli/{cli,compatibility,semantics,support,typed_tree}.rs
Validates API revisions 1-3 and expects diagnostics listing 1-4. Locates context boundaries via macro/documentation markers instead of Display impls. Adds methods block parsing as fn API entries and updates typed-tree expectations for lifetime/state-free context declarations.
Documentation and checksum updates
README.md, third_party/antlr-v4-grammar/self-hosted.sha256
Documents API revision 4 and macro-backed context support with compatibility for revisions 1-3. Updates recorded SHA-256 checksums for regenerated lexer/parser files.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Codegen as Codegen surface (contexts.rs)
  participant Macro as __antlr4_rust_context! macro
  participant Runtime as antlr-rust-runtime
  participant Generated as Generated parser module

  Codegen->>Macro: emit rule attributes and context-kind match
  Macro->>Runtime: expand into stored/active/validated context types
  Runtime-->>Generated: typed context struct with accessors, Display, conversions
  Generated->>Runtime: request compatibility check via __antlr4_rust_require_codegen_api!
  Runtime-->>Generated: confirm revision 4 support (accepts 1-4)
Loading

Possibly related issues

Possibly related PRs

  • ophi-dev/antlr-rust-runtime#270: Modifies generated parser context handling and compatibility/accessor behavior that this PR's macro-based context generation now supports.
  • ophi-dev/antlr-rust-runtime#274: Introduces the generated-code compatibility mechanism this PR extends by raising the API revision from 3 to 4.
  • ophi-dev/antlr-rust-runtime#178: Modifies typed-context accessor generation, including text() and child/token accessors, now centralized in the runtime macro.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive Core changes align with issue #276, but excluded generated files and snapshots prevent verification of complete API parity and acceptance criteria. Provide reviewable evidence for excluded artifacts, parity tests, size measurements, and full validation results.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: centralizing typed context mechanics in code generation.
Out of Scope Changes check ✅ Passed The runtime, generator, compatibility, test, documentation, and checksum changes all support the linked issue objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-276-context-runtime-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@claude

claude Bot commented Aug 4, 2026

Copy link
Copy Markdown

Claude Code is working…

I'll analyze this and get back to you.

View job run

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 25.13966% with 134 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/antlr-rust-runtime/src/generated.rs 17.28% 134 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

📊 Source Code Metrics (this PR vs main)

File Cyclomatic Cognitive Functions LLOC MI
crates/antlr-rust-codegen/src/generator/tests.rs 280 (main: 278) 🔴 48 ⚪ 197 (main: 195) 🔴 1362 (main: 1347) 🔴 0 ⚪
crates/antlr-rust-codegen/src/parser/surface/support_abi.rs 164 (main: 163) 🔴 102 (main: 100) 🔴 31 ⚪ 269 (main: 267) 🔴 0 ⚪
crates/antlr-rust-codegen/src/parser/surface/accessors.rs 236 (main: 237) 🟢 192 ⚪ 28 (main: 29) 🟢 329 (main: 331) 🟢 0 ⚪
crates/antlr-rust-codegen/src/parser/surface/names.rs 65 (main: 64) 🔴 40 (main: 38) 🔴 16 ⚪ 109 (main: 107) 🔴 5.04 (main: 5.26) 🔴
crates/antlr-rust-runtime/src/generated.rs 18 ⚪ 0 ⚪ 12 ⚪ 19 ⚪ 13.31 (main: 23.50) 🔴
crates/antlr-rust-codegen/src/parser/surface/contexts.rs 25 (main: 27) 🟢 22 (main: 26) 🟢 4 ⚪ 72 (main: 90) 🟢 11.52 (main: 10.12) 🟢
crates/antlr-rust-runtime/src/lib.rs 4 ⚪ 3 ⚪ 1 ⚪ 7 ⚪ 29.93 (main: 30.02) 🔴

Generated by mehen v1.8.0 — the code quality watcher.

@tinovyatkin
tinovyatkin merged commit 920bb67 into main Aug 4, 2026
12 of 13 checks passed
@tinovyatkin
tinovyatkin deleted the codex/issue-276-context-runtime-api branch August 4, 2026 16:20
@ophiarch ophiarch Bot mentioned this pull request Aug 4, 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.

codegen: move repeated typed-context mechanics behind the generated-code runtime API

1 participant