mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Detect references to non-existant messages in Fluent resources
This commit is contained in:
parent
5e37043d63
commit
ed707a106c
@ -4,7 +4,10 @@ use annotate_snippets::{
|
||||
};
|
||||
use fluent_bundle::{FluentBundle, FluentError, FluentResource};
|
||||
use fluent_syntax::{
|
||||
ast::{Attribute, Entry, Identifier, Message},
|
||||
ast::{
|
||||
Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern,
|
||||
PatternElement,
|
||||
},
|
||||
parser::ParserError,
|
||||
};
|
||||
use proc_macro::{Diagnostic, Level, Span};
|
||||
@ -185,9 +188,12 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||
};
|
||||
|
||||
let mut constants = TokenStream::new();
|
||||
let mut messagerefs = Vec::new();
|
||||
for entry in resource.entries() {
|
||||
let span = res.krate.span();
|
||||
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
|
||||
if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) =
|
||||
entry
|
||||
{
|
||||
let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
|
||||
|
||||
if name.contains('-') {
|
||||
@ -200,6 +206,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||
.emit();
|
||||
}
|
||||
|
||||
if let Some(Pattern { elements }) = value {
|
||||
for elt in elements {
|
||||
if let PatternElement::Placeable {
|
||||
expression:
|
||||
Expression::Inline(InlineExpression::MessageReference { id, .. }),
|
||||
} = elt
|
||||
{
|
||||
messagerefs.push((id.name, *name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Require that the message name starts with the crate name
|
||||
// `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
|
||||
// `const_eval_baz` (in `const_eval.ftl`)
|
||||
@ -258,6 +276,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||
}
|
||||
}
|
||||
|
||||
for (mref, name) in messagerefs.into_iter() {
|
||||
if !previous_defns.contains_key(mref) {
|
||||
Diagnostic::spanned(
|
||||
path_span,
|
||||
Level::Error,
|
||||
format!("referenced message `{mref}` does not exist (in message `{name}`)"),
|
||||
)
|
||||
.help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(errs) = bundle.add_resource(resource) {
|
||||
for e in errs {
|
||||
match e {
|
||||
|
@ -0,0 +1 @@
|
||||
missing_message_ref = {message}
|
@ -96,3 +96,12 @@ mod missing_crate_name {
|
||||
|
||||
use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens};
|
||||
}
|
||||
|
||||
mod missing_message_ref {
|
||||
use super::fluent_messages;
|
||||
|
||||
fluent_messages! {
|
||||
missing => "./missing-message-ref.ftl"
|
||||
//~^ ERROR referenced message `message` does not exist
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,14 @@ LL | test_crate => "./missing-crate-name.ftl",
|
||||
|
|
||||
= help: replace any '-'s with '_'s
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: referenced message `message` does not exist (in message `missing_message_ref`)
|
||||
--> $DIR/test.rs:104:20
|
||||
|
|
||||
LL | missing => "./missing-message-ref.ftl"
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: you may have meant to use a variable reference (`{$message}`)
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0428`.
|
||||
|
Loading…
Reference in New Issue
Block a user