style: Reduce code size of shorthand serialization

Differential Revision: https://phabricator.services.mozilla.com/D118835
This commit is contained in:
Emilio Cobos Álvarez 2023-05-22 10:00:33 +02:00 committed by Oriol Brufau
parent 58e9ee4d1e
commit 85b7a60a69
3 changed files with 39 additions and 40 deletions

View file

@ -1197,7 +1197,7 @@ pub fn append_declaration_value<'a, 'b: 'a>(
AppendableValue::Css(css) => dest.write_str(css), AppendableValue::Css(css) => dest.write_str(css),
AppendableValue::Declaration(decl) => decl.to_css(dest), AppendableValue::Declaration(decl) => decl.to_css(dest),
AppendableValue::DeclarationsForShorthand(shorthand, decls) => { AppendableValue::DeclarationsForShorthand(shorthand, decls) => {
shorthand.longhands_to_css(decls, &mut CssWriter::new(dest)) shorthand.longhands_to_css(decls, dest)
}, },
} }
} }

View file

@ -845,10 +845,7 @@
impl<'a> LonghandsToSerialize<'a> { impl<'a> LonghandsToSerialize<'a> {
/// Tries to get a serializable set of longhands given a set of /// Tries to get a serializable set of longhands given a set of
/// property declarations. /// property declarations.
pub fn from_iter<I>(iter: I) -> Result<Self, ()> pub fn from_iter(iter: impl Iterator<Item = &'a PropertyDeclaration>) -> Result<Self, ()> {
where
I: Iterator<Item=&'a PropertyDeclaration>,
{
// Define all of the expected variables that correspond to the shorthand // Define all of the expected variables that correspond to the shorthand
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
let mut ${sub_property.ident} = let mut ${sub_property.ident} =
@ -856,8 +853,8 @@
% endfor % endfor
// Attempt to assign the incoming declarations to the expected variables // Attempt to assign the incoming declarations to the expected variables
for longhand in iter { for declaration in iter {
match *longhand { match *declaration {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
PropertyDeclaration::${sub_property.camel_case}(ref value) => { PropertyDeclaration::${sub_property.camel_case}(ref value) => {
${sub_property.ident} = Some(value) ${sub_property.ident} = Some(value)
@ -918,6 +915,14 @@
}) })
} }
/// Try to serialize a given shorthand to a string.
pub fn to_css(declarations: &[&PropertyDeclaration], dest: &mut crate::str::CssStringWriter) -> fmt::Result {
match LonghandsToSerialize::from_iter(declarations.iter().cloned()) {
Ok(longhands) => longhands.to_css(&mut CssWriter::new(dest)),
Err(_) => Ok(())
}
}
${caller.body()} ${caller.body()}
} }
% endif % endif

View file

@ -1471,34 +1471,31 @@ impl ShorthandId {
/// ///
/// Returns an error if writing to the stream fails, or if the declarations /// Returns an error if writing to the stream fails, or if the declarations
/// do not map to a shorthand. /// do not map to a shorthand.
pub fn longhands_to_css<W>( pub fn longhands_to_css(
&self, &self,
declarations: &[&PropertyDeclaration], declarations: &[&PropertyDeclaration],
dest: &mut CssWriter<W>, dest: &mut CssStringWriter,
) -> fmt::Result ) -> fmt::Result {
where type LonghandsToCssFn = for<'a, 'b> fn(&'a [&'b PropertyDeclaration], &mut CssStringWriter) -> fmt::Result;
W: Write, fn all_to_css(_: &[&PropertyDeclaration], _: &mut CssStringWriter) -> fmt::Result {
{ // No need to try to serialize the declarations as the 'all'
// TODO(emilio): Save codesize here by using a lookup table on // shorthand, since it only accepts CSS-wide keywords (and variable
// ShorthandId instead. // references), which will be handled in
let declarations = declarations.iter().cloned(); // get_shorthand_appendable_value.
match *self { Ok(())
ShorthandId::All => {
// No need to try to serialize the declarations as the 'all'
// shorthand, since it only accepts CSS-wide keywords (and
// variable references), which will be handled in
// get_shorthand_appendable_value.
Ok(())
}
% for property in data.shorthands_except_all():
ShorthandId::${property.camel_case} => {
match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) {
Ok(longhands) => longhands.to_css(dest),
Err(_) => Ok(())
}
},
% endfor
} }
static LONGHANDS_TO_CSS: [LonghandsToCssFn; ${len(data.shorthands)}] = [
% for shorthand in data.shorthands:
% if shorthand.ident == "all":
all_to_css,
% else:
shorthands::${shorthand.ident}::to_css,
% endif
% endfor
];
LONGHANDS_TO_CSS[*self as usize](declarations, dest)
} }
/// Finds and returns an appendable value for the given declarations. /// Finds and returns an appendable value for the given declarations.
@ -1591,23 +1588,20 @@ impl ShorthandId {
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<(), ParseError<'i>>; ) -> Result<(), ParseError<'i>>;
fn unreachable<'i, 't>( fn parse_all<'i, 't>(
_: &mut SourcePropertyDeclaration, _: &mut SourcePropertyDeclaration,
_: &ParserContext, _: &ParserContext,
_: &mut Parser<'i, 't> input: &mut Parser<'i, 't>
) -> Result<(), ParseError<'i>> { ) -> Result<(), ParseError<'i>> {
unreachable!() // 'all' accepts no value other than CSS-wide keywords
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
// 'all' accepts no value other than CSS-wide keywords
if *self == ShorthandId::All {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
static PARSE_INTO: [ParseIntoFn; ${len(data.shorthands)}] = [ static PARSE_INTO: [ParseIntoFn; ${len(data.shorthands)}] = [
% for shorthand in data.shorthands: % for shorthand in data.shorthands:
% if shorthand.ident == "all": % if shorthand.ident == "all":
unreachable, parse_all,
% else: % else:
shorthands::${shorthand.ident}::parse_into, shorthands::${shorthand.ident}::parse_into,
% endif % endif