Return shorthand decarations as a new enum, don’t push them to a Vec.

This commit is contained in:
Simon Sapin 2017-03-07 15:58:13 +01:00
parent b11847d86c
commit da6316fbe3
2 changed files with 74 additions and 31 deletions

View file

@ -339,7 +339,7 @@
input.reset(start);
let (first_token_type, css) = try!(
::custom_properties::parse_non_custom_with_var(input));
return Ok(DeclaredValue::WithVariables(Box::new(UnparsedValue {
return Ok(DeclaredValue::WithVariables(Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
base_url: context.base_url.clone(),
@ -483,10 +483,10 @@
#[allow(unused_imports)]
use cssparser::Parser;
use parser::ParserContext;
use properties::{DeclaredValue, PropertyDeclaration};
use properties::{DeclaredValue, PropertyDeclaration, ParsedDeclaration};
use properties::{ShorthandId, UnparsedValue, longhands};
use properties::declaration_block::Importance;
use std::fmt;
use std::sync::Arc;
use style_traits::ToCss;
pub struct Longhands {
@ -551,10 +551,7 @@
/// Parse the given shorthand and fill the result into the
/// `declarations` vector.
pub fn parse(context: &ParserContext,
input: &mut Parser,
declarations: &mut Vec<(PropertyDeclaration, Importance)>)
-> Result<(), ()> {
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<ParsedDeclaration, ()> {
input.look_for_var_functions();
let start = input.position();
let value = input.parse_entirely(|input| parse_value(context, input));
@ -563,31 +560,17 @@
}
let var = input.seen_var_functions();
if let Ok(value) = value {
% for sub_property in shorthand.sub_properties:
declarations.push((PropertyDeclaration::${sub_property.camel_case}(
% if sub_property.boxed:
DeclaredValue::Value(Box::new(value.${sub_property.ident}))
% else:
DeclaredValue::Value(value.${sub_property.ident})
% endif
), Importance::Normal));
% endfor
Ok(())
Ok(ParsedDeclaration::${shorthand.camel_case}(value))
} else if var {
input.reset(start);
let (first_token_type, css) = try!(
::custom_properties::parse_non_custom_with_var(input));
% for sub_property in shorthand.sub_properties:
declarations.push((PropertyDeclaration::${sub_property.camel_case}(
DeclaredValue::WithVariables(Box::new(UnparsedValue {
css: css.clone().into_owned(),
first_token_type: first_token_type,
base_url: context.base_url.clone(),
from_shorthand: Some(ShorthandId::${shorthand.camel_case}),
}))
), Importance::Normal));
% endfor
Ok(())
Ok(ParsedDeclaration::${shorthand.camel_case}WithVariables(Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
base_url: context.base_url.clone(),
from_shorthand: Some(ShorthandId::${shorthand.camel_case}),
})))
} else {
Err(())
}

View file

@ -568,7 +568,7 @@ pub enum DeclaredValue<T> {
/// A known specified value from the stylesheet.
Value(T),
/// An unparsed value that contains `var()` functions.
WithVariables(Box<UnparsedValue>),
WithVariables(Arc<UnparsedValue>),
/// An CSS-wide keyword.
CSSWideKeyword(CSSWideKeyword),
}
@ -797,6 +797,61 @@ impl PropertyId {
}
}
/// Includes shorthands before expansion
pub enum ParsedDeclaration {
% for shorthand in data.shorthands:
/// ${shorthand.name}
${shorthand.camel_case}(shorthands::${shorthand.ident}::Longhands),
% endfor
% for shorthand in data.shorthands:
/// ${shorthand.name} with var() functions
${shorthand.camel_case}WithVariables(Arc<UnparsedValue>),
% endfor
/// Not a shorthand
LonghandOrCustom(PropertyDeclaration),
}
impl ParsedDeclaration {
/// Transform this ParsedDeclaration into a sequence of PropertyDeclaration
/// by expanding shorthand declarations into their corresponding longhands
pub fn expand<F>(self, mut f: F) where F: FnMut(PropertyDeclaration) {
match self {
% for shorthand in data.shorthands:
ParsedDeclaration::${shorthand.camel_case}(
shorthands::${shorthand.ident}::Longhands {
% for sub_property in shorthand.sub_properties:
${sub_property.ident},
% endfor
}
) => {
% for sub_property in shorthand.sub_properties:
f(PropertyDeclaration::${sub_property.camel_case}(
% if sub_property.boxed:
DeclaredValue::Value(Box::new(${sub_property.ident}))
% else:
DeclaredValue::Value(${sub_property.ident})
% endif
));
% endfor
}
% endfor
% for shorthand in data.shorthands:
ParsedDeclaration::${shorthand.camel_case}WithVariables(value) => {
debug_assert_eq!(
value.from_shorthand,
Some(ShorthandId::${shorthand.camel_case})
);
% for sub_property in shorthand.sub_properties:
f(PropertyDeclaration::${sub_property.camel_case}(
DeclaredValue::WithVariables(value.clone())));
% endfor
}
% endfor
ParsedDeclaration::LonghandOrCustom(declaration) => f(declaration),
}
}
}
/// Servo's representation for a property declaration.
#[derive(PartialEq, Clone)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -1075,8 +1130,13 @@ impl PropertyDeclaration {
% endfor
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration
},
Err(()) => match shorthands::${shorthand.ident}::parse(context, input, result_list) {
Ok(()) => PropertyDeclarationParseResult::ValidOrIgnoredDeclaration,
Err(()) => match shorthands::${shorthand.ident}::parse(context, input) {
Ok(parsed) => {
parsed.expand(|declaration| {
result_list.push((declaration, Importance::Normal))
});
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration
}
Err(()) => PropertyDeclarationParseResult::InvalidValue,
}
}