Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,20 @@ Using the same package release for `antlr4-rust-gen` and
`antlr-rust-runtime` remains the recommended workflow, but matching the
generated-code API is the compile-time requirement.

The bundled generator currently emits revision 9, which imports the
grammar-independent generated support surface (the typed terminal/error-node
wrappers, context child-iteration helpers, and embedded-action input facade)
from the runtime's `generated` module instead of re-declaring it in every
generated parser. The runtime also accepts revisions 1 through 8 because
their older generated recognizers use API surfaces that remain available.
The bundled generator currently emits revision 10, which stops re-declaring
the validated-parse surface in every generated parser: `<Grammar>ValidatedTree`
is a type alias of the runtime's `ValidatedTree` branded with the module-local
`ValidatedTreeContext` marker (likewise the module's `ValidatedRuleNode`
alias), `FromValidatedRuleNode` is a re-export of the runtime trait, and
`<Grammar>ValidationError` is an unbranded alias of the runtime's shared
`ValidationError` — so validated trees of different grammars stay distinct
types while all grammars share one error type (per-grammar trait impls on the
error name must collapse into one; see `docs/migration.md`). Revision 9
similarly imports the grammar-independent generated support surface (the typed
terminal/error-node wrappers, context child-iteration helpers, and
embedded-action input facade) from the runtime's `generated` module. The
runtime also accepts revisions 1 through 9 because their older generated
recognizers use API surfaces that remain available.

Generated modules created before this check was introduced cannot be detected
retroactively. When first upgrading to a release that includes the check,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expression: "generated_module_header.replace(env!(\"CARGO_PKG_VERSION\"),\n\"<ge
---
// @generated by antlr-rust-codegen v<generator-version> - do not edit
// project: https://github.com/ophi-dev/antlr-rust-runtime
antlr4_runtime::__antlr4_rust_require_codegen_api!(9, "<generator-version>");
antlr4_runtime::__antlr4_rust_require_codegen_api!(10, "<generator-version>");
#[allow(warnings, missing_docs, clippy::all, clippy::pedantic, clippy::nursery)]
#[rustfmt::skip]
mod __antlr4_rust_generated {
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ antlr4_runtime::__antlr4_rust_context! {
pub struct SContext {
rule_index: 0,
context_kind: any,
validated_downcast: branded,
attributes: {
},
methods: {
Expand All @@ -22,6 +23,7 @@ antlr4_runtime::__antlr4_rust_context! {
pub struct FlagContext {
rule_index: 1,
context_kind: any,
validated_downcast: branded,
attributes: {
__RuleAttrs1 {
enabled: bool,
Expand Down
6 changes: 4 additions & 2 deletions crates/antlr-rust-codegen/src/generator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3088,8 +3088,10 @@ fn renders_parse_convenience_without_replacing_manual_constructor() {
fn validated_parse_names_match_lowercase_grammar_surface() {
let rendered = render_parser("u", &minimal_parser_data()).expect("parser should render");

assert!(rendered.contains("pub struct uValidatedTree"));
assert!(rendered.contains("pub enum uValidationError"));
assert!(rendered.contains(
"pub type uValidatedTree = antlr4_runtime::ValidatedTree<ValidatedTreeContext>;"
));
assert!(rendered.contains("pub type uValidationError = antlr4_runtime::ValidationError;"));
assert!(rendered.contains("pub fn validate(self) -> Result<uValidatedTree, uValidationError>"));
assert!(!rendered.contains("UValidatedTree"));
assert!(!rendered.contains("UValidationError"));
Expand Down
36 changes: 4 additions & 32 deletions crates/antlr-rust-codegen/src/parser/surface/accessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,15 +644,8 @@ struct RenderedContextAccessors {
compatibility: String,
}

fn render_required_accessor_validation(
out: &mut String,
method: &str,
validation_error_name: &str,
) {
let _ = writeln!(
out,
" let _ = context.{method}().map_err({validation_error_name}::MissingChild)?;"
);
fn render_required_accessor_validation(out: &mut String, method: &str) {
let _ = writeln!(out, " context.{method}()?;");
}

fn render_repeated_accessor_validation(
Expand All @@ -661,14 +654,13 @@ fn render_repeated_accessor_validation(
view_name: &str,
child_name: &str,
minimum: usize,
validation_error_name: &str,
) {
if minimum == 0 {
return;
}
let _ = writeln!(
out,
" {{\n let actual = context.{method}().count();\n if actual < {minimum} {{\n return Err({validation_error_name}::InvalidChildCount {{\n context: \"{view_name}\",\n child: \"{child_name}\",\n minimum: {minimum},\n actual,\n }});\n }}\n }}"
" antlr4_runtime::require_min_count(context.{method}().count(), {minimum}, \"{view_name}\", \"{child_name}\")?;"
);
}

Expand Down Expand Up @@ -887,7 +879,6 @@ struct RuleLabelAccessorRender<'a> {
child_view: &'a str,
child_index: usize,
label: &'a ContextLabelAccessor,
validation_error_name: &'a str,
}

fn render_rule_label_accessor(
Expand All @@ -900,7 +891,6 @@ fn render_rule_label_accessor(
child_view,
child_index,
label,
validation_error_name,
} = context;
if let ContextLabelSelector::AllAfter(skip) = label.selector {
let _ = writeln!(
Expand All @@ -913,7 +903,6 @@ fn render_rule_label_accessor(
view_name,
&label.source_name,
label.cardinality.min,
validation_error_name,
);
return;
}
Expand All @@ -931,7 +920,6 @@ fn render_rule_label_accessor(
render_required_accessor_validation(
&mut rendered.validation,
method,
validation_error_name,
);
} else {
let _ = writeln!(
Expand All @@ -946,7 +934,6 @@ fn render_token_label_accessor(
method: &str,
view_name: &str,
label: &ContextLabelAccessor,
validation_error_name: &str,
) {
let token_types = label
.token_types
Expand All @@ -965,7 +952,6 @@ fn render_token_label_accessor(
view_name,
&label.source_name,
label.cardinality.min,
validation_error_name,
);
return;
}
Expand All @@ -983,7 +969,6 @@ fn render_token_label_accessor(
render_required_accessor_validation(
&mut rendered.validation,
method,
validation_error_name,
);
} else {
let _ = writeln!(
Expand All @@ -1001,7 +986,6 @@ struct ContextAccessorsRender<'a> {
token_accessors: &'a [(String, i32)],
child_cardinalities: &'a BTreeMap<String, embedded::ChildCardinality>,
label_accessors: &'a [ContextLabelAccessor],
validation_error_name: &'a str,
antlr4rust_compat: bool,
antlr4rust_context_wrapper: &'a str,
common_methods: &'a ContextCommonMethodNames,
Expand All @@ -1015,7 +999,6 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
token_accessors,
child_cardinalities,
label_accessors,
validation_error_name,
antlr4rust_compat,
antlr4rust_context_wrapper,
common_methods,
Expand Down Expand Up @@ -1056,7 +1039,6 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
view_name,
&child.name,
cardinality.min,
validation_error_name,
);
if antlr4rust_compat {
render_antlr4rust_indexed_rule_accessor(
Expand Down Expand Up @@ -1085,7 +1067,6 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
render_required_accessor_validation(
&mut rendered.validation,
&method,
validation_error_name,
);
} else {
let _ = writeln!(
Expand Down Expand Up @@ -1134,7 +1115,6 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
view_name,
token_name,
cardinality.min,
validation_error_name,
);
if antlr4rust_compat {
render_antlr4rust_indexed_token_accessor(
Expand All @@ -1158,7 +1138,6 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
render_required_accessor_validation(
&mut rendered.validation,
&method,
validation_error_name,
);
if antlr4rust_compat {
render_antlr4rust_single_token_accessor(
Expand Down Expand Up @@ -1207,21 +1186,14 @@ fn render_context_child_accessors(context: ContextAccessorsRender<'_>) -> Render
child_view,
child_index,
label,
validation_error_name,
},
);
continue;
}
if label.token_types.is_empty() {
continue;
}
render_token_label_accessor(
&mut rendered,
&method,
view_name,
label,
validation_error_name,
);
render_token_label_accessor(&mut rendered, &method, view_name, label);
}
rendered
}
3 changes: 1 addition & 2 deletions crates/antlr-rust-codegen/src/parser/surface/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<T> std::ops::Deref for {antlr4rust_context_wrapper}<T> {{
}
let _ = writeln!(
out,
"antlr4_runtime::__antlr4_rust_context! {{\n pub struct {view_name} {{\n rule_index: {rule_index},\n context_kind: {context_kind_match},\n attributes: {{\n{attributes} }},\n methods: {{\n rule_node: {rule_node_method},\n child_count: {child_count},\n direct_terminals: {direct_terminals},\n start: {start},\n text: {text},\n }}\n }}\n}}\n",
"antlr4_runtime::__antlr4_rust_context! {{\n pub struct {view_name} {{\n rule_index: {rule_index},\n context_kind: {context_kind_match},\n validated_downcast: branded,\n attributes: {{\n{attributes} }},\n methods: {{\n rule_node: {rule_node_method},\n child_count: {child_count},\n direct_terminals: {direct_terminals},\n start: {start},\n text: {text},\n }}\n }}\n}}\n",
child_count = common_methods.child_count,
direct_terminals = common_methods.direct_terminals,
start = common_methods.start,
Expand All @@ -131,7 +131,6 @@ impl<T> std::ops::Deref for {antlr4rust_context_wrapper}<T> {{
token_accessors: &token_accessors,
child_cardinalities: &child_cardinalities,
label_accessors: &label_accessors,
validation_error_name: &validation_error,
antlr4rust_compat,
antlr4rust_context_wrapper,
common_methods: &common_methods,
Expand Down
Loading
Loading