mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Generate fluent message constant in a flat module for all crates
This will make it easier to grep for fluent message names.
This commit is contained in:
parent
6c9c2d862d
commit
2459569776
@ -25,18 +25,18 @@ use syn::{
|
|||||||
use unic_langid::langid;
|
use unic_langid::langid;
|
||||||
|
|
||||||
struct Resource {
|
struct Resource {
|
||||||
ident: Ident,
|
krate: Ident,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fat_arrow_token: token::FatArrow,
|
fat_arrow_token: token::FatArrow,
|
||||||
resource: LitStr,
|
resource_path: LitStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Resource {
|
impl Parse for Resource {
|
||||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||||
Ok(Resource {
|
Ok(Resource {
|
||||||
ident: input.parse()?,
|
krate: input.parse()?,
|
||||||
fat_arrow_token: input.parse()?,
|
fat_arrow_token: input.parse()?,
|
||||||
resource: input.parse()?,
|
resource_path: input.parse()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,19 +94,20 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
|||||||
// diagnostics.
|
// diagnostics.
|
||||||
let mut previous_defns = HashMap::new();
|
let mut previous_defns = HashMap::new();
|
||||||
|
|
||||||
|
// Set of Fluent attribute names already output, to avoid duplicate type errors - any given
|
||||||
|
// constant created for a given attribute is the same.
|
||||||
|
let mut previous_attrs = HashSet::new();
|
||||||
|
|
||||||
let mut includes = TokenStream::new();
|
let mut includes = TokenStream::new();
|
||||||
let mut generated = TokenStream::new();
|
let mut generated = TokenStream::new();
|
||||||
|
|
||||||
for res in resources.0 {
|
for res in resources.0 {
|
||||||
let ident_span = res.ident.span().unwrap();
|
let krate_span = res.krate.span().unwrap();
|
||||||
let path_span = res.resource.span().unwrap();
|
let path_span = res.resource_path.span().unwrap();
|
||||||
|
|
||||||
// Set of Fluent attribute names already output, to avoid duplicate type errors - any given
|
let relative_ftl_path = res.resource_path.value();
|
||||||
// constant created for a given attribute is the same.
|
|
||||||
let mut previous_attrs = HashSet::new();
|
|
||||||
|
|
||||||
let relative_ftl_path = res.resource.value();
|
|
||||||
let absolute_ftl_path =
|
let absolute_ftl_path =
|
||||||
invocation_relative_path_to_absolute(ident_span, &relative_ftl_path);
|
invocation_relative_path_to_absolute(krate_span, &relative_ftl_path);
|
||||||
// As this macro also outputs an `include_str!` for this file, the macro will always be
|
// As this macro also outputs an `include_str!` for this file, the macro will always be
|
||||||
// re-executed when the file changes.
|
// re-executed when the file changes.
|
||||||
let mut resource_file = match File::open(absolute_ftl_path) {
|
let mut resource_file = match File::open(absolute_ftl_path) {
|
||||||
@ -185,7 +186,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
|||||||
|
|
||||||
let mut constants = TokenStream::new();
|
let mut constants = TokenStream::new();
|
||||||
for entry in resource.entries() {
|
for entry in resource.entries() {
|
||||||
let span = res.ident.span();
|
let span = res.krate.span();
|
||||||
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
|
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
|
||||||
let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
|
let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
|
||||||
|
|
||||||
@ -199,29 +200,30 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
|||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
|
// Require that the message name starts with the crate name
|
||||||
// `const_eval_baz` => `baz` (in `const_eval.ftl`)
|
// `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
|
||||||
|
// `const_eval_baz` (in `const_eval.ftl`)
|
||||||
// `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
|
// `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
|
||||||
// The last case we error about above, but we want to fall back gracefully
|
// The last case we error about above, but we want to fall back gracefully
|
||||||
// so that only the error is being emitted and not also one about the macro
|
// so that only the error is being emitted and not also one about the macro
|
||||||
// failing.
|
// failing.
|
||||||
let crate_prefix = format!("{}_", res.ident);
|
let crate_prefix = format!("{}_", res.krate);
|
||||||
|
|
||||||
let snake_name = name.replace('-', "_");
|
let snake_name = name.replace('-', "_");
|
||||||
let snake_name = match snake_name.strip_prefix(&crate_prefix) {
|
if !snake_name.starts_with(&crate_prefix) {
|
||||||
Some(rest) => Ident::new(rest, span),
|
Diagnostic::spanned(
|
||||||
None => {
|
path_span,
|
||||||
Diagnostic::spanned(
|
Level::Error,
|
||||||
path_span,
|
format!("name `{name}` does not start with the crate name"),
|
||||||
Level::Error,
|
)
|
||||||
format!("name `{name}` does not start with the crate name"),
|
.help(format!(
|
||||||
)
|
"prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"
|
||||||
.help(format!("prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`"))
|
))
|
||||||
.emit();
|
.emit();
|
||||||
Ident::new(&snake_name, span)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let snake_name = Ident::new(&snake_name, span);
|
||||||
|
|
||||||
constants.extend(quote! {
|
constants.extend(quote! {
|
||||||
pub const #snake_name: crate::DiagnosticMessage =
|
pub const #snake_name: crate::DiagnosticMessage =
|
||||||
crate::DiagnosticMessage::FluentIdentifier(
|
crate::DiagnosticMessage::FluentIdentifier(
|
||||||
@ -275,12 +277,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
|||||||
|
|
||||||
includes.extend(quote! { include_str!(#relative_ftl_path), });
|
includes.extend(quote! { include_str!(#relative_ftl_path), });
|
||||||
|
|
||||||
let ident = res.ident;
|
generated.extend(constants);
|
||||||
generated.extend(quote! {
|
|
||||||
pub mod #ident {
|
|
||||||
#constants
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
Loading…
Reference in New Issue
Block a user