Replace ParsedDeclaration::expand with non-generic method

... to reduce its code size impact.

https://bugzilla.mozilla.org/show_bug.cgi?id=1351737
This commit is contained in:
Simon Sapin 2017-03-29 20:14:41 +02:00
parent 3345b83fb3
commit 4f2b9a33fe
5 changed files with 70 additions and 36 deletions

View file

@ -272,10 +272,7 @@ impl CSSStyleDeclaration {
// Step 8 // Step 8
// Step 9 // Step 9
*changed = false; *changed = parsed.expand_set_into(pdb, importance);
parsed.expand(|declaration| {
*changed |= pdb.set_parsed_declaration(declaration, importance);
});
Ok(()) Ok(())
}) })

View file

@ -374,7 +374,7 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
let mut block = PropertyDeclarationBlock::new(); let mut block = PropertyDeclarationBlock::new();
while let Some(declaration) = iter.next() { while let Some(declaration) = iter.next() {
match declaration { match declaration {
Ok(parsed) => parsed.expand(|d| block.push(d, Importance::Normal)), Ok(parsed) => parsed.expand_push_into(&mut block, Importance::Normal),
Err(range) => { Err(range) => {
let pos = range.start; let pos = range.start;
let message = format!("Unsupported keyframe property declaration: '{}'", let message = format!("Unsupported keyframe property declaration: '{}'",

View file

@ -88,7 +88,7 @@ impl PropertyDeclarationBlock {
&self.declarations &self.declarations
} }
/// Returns wheather this block contains any declaration with `!important`. /// Returns whether this block contains any declaration with `!important`.
/// ///
/// This is based on the `important_count` counter, /// This is based on the `important_count` counter,
/// which should be maintained whenever `declarations` is changed. /// which should be maintained whenever `declarations` is changed.
@ -97,7 +97,7 @@ impl PropertyDeclarationBlock {
self.important_count > 0 self.important_count > 0
} }
/// Returns wheather this block contains any declaration without `!important`. /// Returns whether this block contains any declaration without `!important`.
/// ///
/// This is based on the `important_count` counter, /// This is based on the `important_count` counter,
/// which should be maintained whenever `declarations` is changed. /// which should be maintained whenever `declarations` is changed.
@ -202,16 +202,9 @@ impl PropertyDeclarationBlock {
self.push_common(declaration, importance, false); self.push_common(declaration, importance, false);
} }
/// Adds or overrides the declaration for a given property in this block, /// Implementation detail of push and ParsedDeclaration::expand*
/// Returns whether the declaration block is actually changed. pub fn push_common(&mut self, declaration: PropertyDeclaration, importance: Importance,
pub fn set_parsed_declaration(&mut self, overwrite_more_important: bool) -> bool {
declaration: PropertyDeclaration,
importance: Importance) -> bool {
self.push_common(declaration, importance, true)
}
fn push_common(&mut self, declaration: PropertyDeclaration, importance: Importance,
overwrite_more_important: bool) -> bool {
let definitely_new = if let PropertyDeclarationId::Longhand(id) = declaration.id() { let definitely_new = if let PropertyDeclarationId::Longhand(id) = declaration.id() {
!self.longhands.contains(id) !self.longhands.contains(id)
} else { } else {
@ -697,7 +690,7 @@ pub fn parse_property_declaration_list(context: &ParserContext,
let mut iter = DeclarationListParser::new(input, parser); let mut iter = DeclarationListParser::new(input, parser);
while let Some(declaration) = iter.next() { while let Some(declaration) = iter.next() {
match declaration { match declaration {
Ok((parsed, importance)) => parsed.expand(|d| block.push(d, importance)), Ok((parsed, importance)) => parsed.expand_push_into(&mut block, importance),
Err(range) => { Err(range) => {
let pos = range.start; let pos = range.start;
let message = format!("Unsupported property declaration: '{}'", let message = format!("Unsupported property declaration: '{}'",

View file

@ -888,7 +888,29 @@ pub enum ParsedDeclaration {
impl ParsedDeclaration { impl ParsedDeclaration {
/// Transform this ParsedDeclaration into a sequence of PropertyDeclaration /// Transform this ParsedDeclaration into a sequence of PropertyDeclaration
/// by expanding shorthand declarations into their corresponding longhands /// by expanding shorthand declarations into their corresponding longhands
pub fn expand<F>(self, mut push: F) where F: FnMut(PropertyDeclaration) { ///
/// Adds or overrides exsting declarations in the given block,
/// except if existing declarations are more important.
#[inline]
pub fn expand_push_into(self, block: &mut PropertyDeclarationBlock,
importance: Importance) {
self.expand_into(block, importance, false);
}
/// Transform this ParsedDeclaration into a sequence of PropertyDeclaration
/// by expanding shorthand declarations into their corresponding longhands
///
/// Add or override existing declarations in the given block.
/// Return whether anything changed.
#[inline]
pub fn expand_set_into(self, block: &mut PropertyDeclarationBlock,
importance: Importance) -> bool {
self.expand_into(block, importance, true)
}
fn expand_into(self, block: &mut PropertyDeclarationBlock,
importance: Importance,
overwrite_more_important: bool) -> bool {
match self { match self {
% for shorthand in data.shorthands: % for shorthand in data.shorthands:
ParsedDeclaration::${shorthand.camel_case}( ParsedDeclaration::${shorthand.camel_case}(
@ -898,32 +920,58 @@ impl ParsedDeclaration {
% endfor % endfor
} }
) => { ) => {
let mut changed = false;
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
push(PropertyDeclaration::${sub_property.camel_case}( changed |= block.push_common(
% if sub_property.boxed: PropertyDeclaration::${sub_property.camel_case}(
Box::new(${sub_property.ident}) % if sub_property.boxed:
% else: Box::new(${sub_property.ident})
${sub_property.ident} % else:
% endif ${sub_property.ident}
)); % endif
),
importance,
overwrite_more_important,
);
% endfor % endfor
changed
}, },
ParsedDeclaration::${shorthand.camel_case}CSSWideKeyword(keyword) => { ParsedDeclaration::${shorthand.camel_case}CSSWideKeyword(keyword) => {
let mut changed = false;
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
push(PropertyDeclaration::CSSWideKeyword(LonghandId::${sub_property.camel_case}, keyword)); changed |= block.push_common(
PropertyDeclaration::CSSWideKeyword(
LonghandId::${sub_property.camel_case},
keyword,
),
importance,
overwrite_more_important,
);
% endfor % endfor
changed
}, },
ParsedDeclaration::${shorthand.camel_case}WithVariables(value) => { ParsedDeclaration::${shorthand.camel_case}WithVariables(value) => {
debug_assert_eq!( debug_assert_eq!(
value.from_shorthand, value.from_shorthand,
Some(ShorthandId::${shorthand.camel_case}) Some(ShorthandId::${shorthand.camel_case})
); );
let mut changed = false;
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
push(PropertyDeclaration::WithVariables(LonghandId::${sub_property.camel_case}, value.clone())); changed |= block.push_common(
PropertyDeclaration::WithVariables(
LonghandId::${sub_property.camel_case},
value.clone()
),
importance,
overwrite_more_important,
);
% endfor % endfor
changed
} }
% endfor % endfor
ParsedDeclaration::LonghandOrCustom(declaration) => push(declaration), ParsedDeclaration::LonghandOrCustom(declaration) => {
block.push_common(declaration, importance, overwrite_more_important)
}
} }
} }

View file

@ -800,7 +800,7 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const
Ok(parsed) => { Ok(parsed) => {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let mut block = PropertyDeclarationBlock::new(); let mut block = PropertyDeclarationBlock::new();
parsed.expand(|d| block.push(d, Importance::Normal)); parsed.expand_push_into(&mut block, Importance::Normal);
Arc::new(global_style_data.shared_lock.wrap(block)).into_strong() Arc::new(global_style_data.shared_lock.wrap(block)).into_strong()
} }
Err(_) => RawServoDeclarationBlockStrong::null() Err(_) => RawServoDeclarationBlockStrong::null()
@ -958,13 +958,9 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro
if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url, if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url,
&StdoutErrorReporter, extra_data) { &StdoutErrorReporter, extra_data) {
let importance = if is_important { Importance::Important } else { Importance::Normal }; let importance = if is_important { Importance::Important } else { Importance::Normal };
let mut changed = false;
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| { write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
parsed.expand(|decl| { parsed.expand_set_into(decls, importance)
changed |= decls.set_parsed_declaration(decl, importance); })
});
});
changed
} else { } else {
false false
} }