errors: simplify referring to fluent attributes
To render the message of a Fluent attribute, the identifier of the Fluent message must be known. `DiagnosticMessage::FluentIdentifier` contains both the message's identifier and optionally the identifier of an attribute. Generated constants for each attribute would therefore need to be named uniquely (amongst all error messages) or be able to refer to only the attribute identifier which will be combined with a message identifier later. In this commit, the latter strategy is implemented as part of the `Diagnostic` type's functions for adding subdiagnostics of various kinds. Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
parent
855fc022fe
commit
f669b78ffc
13 changed files with 190 additions and 150 deletions
|
@ -234,6 +234,48 @@ pub fn fallback_fluent_bundle(
|
|||
/// Identifier for the Fluent message/attribute corresponding to a diagnostic message.
|
||||
type FluentId = Cow<'static, str>;
|
||||
|
||||
/// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both
|
||||
/// translatable and non-translatable diagnostic messages.
|
||||
///
|
||||
/// Translatable messages for subdiagnostics are typically attributes attached to a larger Fluent
|
||||
/// message so messages of this type must be combined with a `DiagnosticMessage` (using
|
||||
/// `DiagnosticMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from
|
||||
/// the `SessionSubdiagnostic` derive refer to Fluent identifiers directly.
|
||||
pub enum SubdiagnosticMessage {
|
||||
/// Non-translatable diagnostic message.
|
||||
// FIXME(davidtwco): can a `Cow<'static, str>` be used here?
|
||||
Str(String),
|
||||
/// Identifier of a Fluent message. Instances of this variant are generated by the
|
||||
/// `SessionSubdiagnostic` derive.
|
||||
FluentIdentifier(FluentId),
|
||||
/// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an
|
||||
/// actual translated message. Instances of this variant are generated by the `fluent_messages`
|
||||
/// macro.
|
||||
///
|
||||
/// <https://projectfluent.org/fluent/guide/attributes.html>
|
||||
FluentAttr(FluentId),
|
||||
}
|
||||
|
||||
impl SubdiagnosticMessage {
|
||||
/// Create a `SubdiagnosticMessage` for the provided Fluent attribute.
|
||||
pub fn attr(id: impl Into<FluentId>) -> Self {
|
||||
SubdiagnosticMessage::FluentAttr(id.into())
|
||||
}
|
||||
|
||||
/// Create a `SubdiagnosticMessage` for the provided Fluent identifier.
|
||||
pub fn message(id: impl Into<FluentId>) -> Self {
|
||||
SubdiagnosticMessage::FluentIdentifier(id.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// `From` impl that enables existing diagnostic calls to functions which now take
|
||||
/// `impl Into<SubdiagnosticMessage>` to continue to work as before.
|
||||
impl<S: Into<String>> From<S> for SubdiagnosticMessage {
|
||||
fn from(s: S) -> Self {
|
||||
SubdiagnosticMessage::Str(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction over a message in a diagnostic to support both translatable and non-translatable
|
||||
/// diagnostic messages.
|
||||
///
|
||||
|
@ -252,6 +294,29 @@ pub enum DiagnosticMessage {
|
|||
}
|
||||
|
||||
impl DiagnosticMessage {
|
||||
/// Given a `SubdiagnosticMessage` which may contain a Fluent attribute, create a new
|
||||
/// `DiagnosticMessage` that combines that attribute with the Fluent identifier of `self`.
|
||||
///
|
||||
/// - If the `SubdiagnosticMessage` is non-translatable then return the message as a
|
||||
/// `DiagnosticMessage`.
|
||||
/// - If `self` is non-translatable then return `self`'s message.
|
||||
pub fn with_subdiagnostic_message(&self, sub: SubdiagnosticMessage) -> Self {
|
||||
let attr = match sub {
|
||||
SubdiagnosticMessage::Str(s) => return DiagnosticMessage::Str(s.clone()),
|
||||
SubdiagnosticMessage::FluentIdentifier(id) => {
|
||||
return DiagnosticMessage::FluentIdentifier(id, None);
|
||||
}
|
||||
SubdiagnosticMessage::FluentAttr(attr) => attr,
|
||||
};
|
||||
|
||||
match self {
|
||||
DiagnosticMessage::Str(s) => DiagnosticMessage::Str(s.clone()),
|
||||
DiagnosticMessage::FluentIdentifier(id, _) => {
|
||||
DiagnosticMessage::FluentIdentifier(id.clone(), Some(attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that
|
||||
/// this diagnostic message is of the legacy, non-translatable variety. Panics if this
|
||||
/// assumption does not hold.
|
||||
|
@ -266,14 +331,9 @@ impl DiagnosticMessage {
|
|||
}
|
||||
|
||||
/// Create a `DiagnosticMessage` for the provided Fluent identifier.
|
||||
pub fn fluent(id: impl Into<FluentId>) -> Self {
|
||||
pub fn new(id: impl Into<FluentId>) -> Self {
|
||||
DiagnosticMessage::FluentIdentifier(id.into(), None)
|
||||
}
|
||||
|
||||
/// Create a `DiagnosticMessage` for the provided Fluent identifier and attribute.
|
||||
pub fn fluent_attr(id: impl Into<FluentId>, attr: impl Into<FluentId>) -> Self {
|
||||
DiagnosticMessage::FluentIdentifier(id.into(), Some(attr.into()))
|
||||
}
|
||||
}
|
||||
|
||||
/// `From` impl that enables existing diagnostic calls to functions which now take
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue