diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2023-05-05 21:26:42 +0100 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2023-05-26 10:41:36 +0000 |
| commit | 9b5574f028c75d794b51c96ff6471ddf756f329b (patch) | |
| tree | d57f45ebda8ac979c9e83b43963a0877cec544b6 /compiler/rustc_fluent_macro | |
| parent | be72f2587c91579406117f99fa332383d66b7dcd (diff) | |
| download | rust-9b5574f028c75d794b51c96ff6471ddf756f329b.tar.gz rust-9b5574f028c75d794b51c96ff6471ddf756f329b.zip | |
Validate fluent variable references with `debug_assertions`
Diffstat (limited to 'compiler/rustc_fluent_macro')
| -rw-r--r-- | compiler/rustc_fluent_macro/src/fluent.rs | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 9dffc9a7645..b1c83e0dedc 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -179,7 +179,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok let mut previous_defns = HashMap::new(); let mut message_refs = Vec::new(); for entry in resource.entries() { - if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = entry { + if let Entry::Message(msg) = entry { + let Message { id: Identifier { name }, attributes, value, .. } = msg; let _ = previous_defns.entry(name.to_string()).or_insert(resource_span); if name.contains('-') { Diagnostic::spanned( @@ -229,9 +230,10 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok continue; } - let msg = format!("Constant referring to Fluent message `{name}` from `{crate_name}`"); + let docstr = + format!("Constant referring to Fluent message `{name}` from `{crate_name}`"); constants.extend(quote! { - #[doc = #msg] + #[doc = #docstr] pub const #snake_name: crate::DiagnosticMessage = crate::DiagnosticMessage::FluentIdentifier( std::borrow::Cow::Borrowed(#name), @@ -269,6 +271,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok ); }); } + #[cfg(debug_assertions)] + { + // Record variables referenced by these messages so we can produce + // tests in the derive diagnostics to validate them. + let ident = quote::format_ident!("{snake_name}_refs"); + let vrefs = variable_references(msg); + constants.extend(quote! { + #[cfg(test)] + pub const #ident: &[&str] = &[#(#vrefs),*]; + }) + } } } @@ -334,3 +347,29 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok } .into() } + +#[cfg(debug_assertions)] +fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> { + let mut refs = vec![]; + if let Some(Pattern { elements }) = &msg.value { + for elt in elements { + if let PatternElement::Placeable { + expression: Expression::Inline(InlineExpression::VariableReference { id }), + } = elt + { + refs.push(id.name); + } + } + } + for attr in &msg.attributes { + for elt in &attr.value.elements { + if let PatternElement::Placeable { + expression: Expression::Inline(InlineExpression::VariableReference { id }), + } = elt + { + refs.push(id.name); + } + } + } + refs +} |
