Box large components of Longhands structs.

This commit is contained in:
Simon Sapin 2017-05-19 13:02:46 +02:00
parent 5c57ff890c
commit e4f241389e
17 changed files with 124 additions and 87 deletions

View file

@ -748,7 +748,7 @@
#[allow(unused_imports)]
use cssparser::Parser;
use parser::ParserContext;
use properties::{PropertyDeclaration, ParsedDeclaration};
use properties::{PropertyDeclaration, ParsedDeclaration, MaybeBoxed};
use properties::{ShorthandId, UnparsedValue, longhands};
use std::fmt;
use stylearc::Arc;
@ -756,7 +756,15 @@
pub struct Longhands {
% for sub_property in shorthand.sub_properties:
pub ${sub_property.ident}: longhands::${sub_property.ident}::SpecifiedValue,
pub ${sub_property.ident}:
% if sub_property.boxed:
Box<
% endif
longhands::${sub_property.ident}::SpecifiedValue
% if sub_property.boxed:
>
% endif
,
% endfor
}
@ -865,7 +873,7 @@
try!(parse_four_sides(input, ${parser_function}));
let _unused = context;
% endif
Ok(Longhands {
Ok(expanded! {
% for side in ["top", "right", "bottom", "left"]:
${to_rust_ident(sub_property_pattern % side)}: ${side},
% endfor

View file

@ -58,6 +58,35 @@ macro_rules! property_name {
#[path="${repr(os.path.join(os.path.dirname(__file__), 'declaration_block.rs'))[1:-1]}"]
pub mod declaration_block;
/// Conversion with fewer impls than From/Into
pub trait MaybeBoxed<Out> {
/// Convert
fn maybe_boxed(self) -> Out;
}
impl<T> MaybeBoxed<T> for T {
#[inline]
fn maybe_boxed(self) -> T { self }
}
impl<T> MaybeBoxed<Box<T>> for T {
#[inline]
fn maybe_boxed(self) -> Box<T> { Box::new(self) }
}
macro_rules! expanded {
( $( $name: ident: $value: expr ),+ ) => {
expanded!( $( $name: $value, )+ )
};
( $( $name: ident: $value: expr, )+ ) => {
Longhands {
$(
$name: MaybeBoxed::maybe_boxed($value),
)+
}
}
}
/// A module with all the code for longhand properties.
#[allow(missing_docs)]
pub mod longhands {
@ -405,11 +434,7 @@ impl PropertyDeclarationIdSet {
Some(ShorthandId::${shorthand.camel_case}) => {
shorthands::${shorthand.ident}::parse_value(&context, input)
.map(|result| {
% if property.boxed:
DeclaredValueOwned::Value(Box::new(result.${property.ident}))
% else:
DeclaredValueOwned::Value(result.${property.ident})
% endif
DeclaredValueOwned::Value(result.${property.ident})
})
}
% endif
@ -1039,11 +1064,7 @@ impl ParsedDeclaration {
% for sub_property in shorthand.sub_properties:
changed |= block.push_common(
PropertyDeclaration::${sub_property.camel_case}(
% if sub_property.boxed:
Box::new(${sub_property.ident})
% else:
${sub_property.ident}
% endif
${sub_property.ident}
),
importance,
overwrite_more_important,

View file

@ -108,7 +108,7 @@
}
}));
Ok(Longhands {
Ok(expanded! {
background_color: background_color.unwrap_or(CSSColor::transparent()),
background_image: background_image,
background_position_x: background_position_x,
@ -207,7 +207,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
background_position_x: position_x,
background_position_y: position_y,
})

View file

@ -24,7 +24,7 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style",
let (top, right, bottom, left) = try!(parse_four_sides(input, |i| {
BorderWidth::parse_quirky(context, i, AllowQuirks::Yes)
}));
Ok(Longhands {
Ok(expanded! {
% for side in PHYSICAL_SIDES:
${to_rust_ident('border-%s-width' % side)}: ${side},
% endfor
@ -103,7 +103,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let (color, style, width) = try!(super::parse_border(context, input));
Ok(Longhands {
Ok(expanded! {
border_${to_rust_ident(side)}_color: color,
border_${to_rust_ident(side)}_style: style,
border_${to_rust_ident(side)}_width: width
@ -144,7 +144,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
use properties::longhands::{border_image_source, border_image_width};
let (color, style, width) = try!(super::parse_border(context, input));
Ok(Longhands {
Ok(expanded! {
% for side in PHYSICAL_SIDES:
border_${side}_color: color.clone(),
border_${side}_style: style,
@ -211,7 +211,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let radii = try!(BorderRadius::parse(context, input));
Ok(Longhands {
Ok(expanded! {
border_top_left_radius: radii.top_left,
border_top_right_radius: radii.top_right,
border_bottom_right_radius: radii.bottom_right,
@ -303,7 +303,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
}
}));
Ok(Longhands {
Ok(expanded! {
% for name in "outset repeat slice source width".split():
border_image_${name}: border_image_${name},
% endfor

View file

@ -16,19 +16,19 @@
let moz_kw_found = input.try(|i| match_ignore_ascii_case! {
&i.expect_ident()?,
"-moz-scrollbars-horizontal" => {
Ok(Longhands {
Ok(expanded! {
overflow_x: SpecifiedValue::scroll,
overflow_y: SpecifiedValue::hidden,
})
}
"-moz-scrollbars-vertical" => {
Ok(Longhands {
Ok(expanded! {
overflow_x: SpecifiedValue::hidden,
overflow_y: SpecifiedValue::scroll,
})
}
"-moz-scrollbars-none" => {
Ok(Longhands {
Ok(expanded! {
overflow_x: SpecifiedValue::hidden,
overflow_y: SpecifiedValue::hidden,
})
@ -40,7 +40,7 @@
}
% endif
let overflow = try!(parse_overflow(context, input));
Ok(Longhands {
Ok(expanded! {
overflow_x: overflow,
overflow_y: overflow,
})
@ -148,7 +148,7 @@ macro_rules! try_parse_one {
% endfor
}
Ok(Longhands {
Ok(expanded! {
% for prop in "property duration timing_function delay".split():
transition_${prop}: transition_${prop}::SpecifiedValue(${prop}s),
% endfor
@ -259,7 +259,7 @@ macro_rules! try_parse_one {
% endfor
}
Ok(Longhands {
Ok(expanded! {
% for prop in props:
animation_${prop}: animation_${prop}::SpecifiedValue(${prop}s),
% endfor
@ -305,7 +305,7 @@ macro_rules! try_parse_one {
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let result = try!(scroll_snap_type_x::parse(context, input));
Ok(Longhands {
Ok(expanded! {
scroll_snap_type_x: result,
scroll_snap_type_y: result,
})
@ -332,7 +332,7 @@ macro_rules! try_parse_one {
use properties::longhands::transform;
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
Ok(Longhands {
Ok(expanded! {
transform: transform::parse_prefixed(context, input)?,
})
}

View file

@ -42,7 +42,7 @@
if values == 0 || values > 2 {
Err(())
} else {
Ok(Longhands {
Ok(expanded! {
column_count: unwrap_or_initial!(column_count),
column_width: unwrap_or_initial!(column_width),
})
@ -86,7 +86,7 @@
break
}
if any {
Ok(Longhands {
Ok(expanded! {
column_rule_width: unwrap_or_initial!(column_rule_width),
column_rule_style: unwrap_or_initial!(column_rule_style),
column_rule_color: unwrap_or_initial!(column_rule_color),

View file

@ -44,7 +44,7 @@
let size;
% if product == "gecko":
if let Ok(sys) = input.try(SystemFont::parse) {
return Ok(Longhands {
return Ok(expanded! {
% for name in SYSTEM_FONT_LONGHANDS:
${name}: ${name}::SpecifiedValue::system_font(sys),
% endfor
@ -102,7 +102,7 @@
None
};
let family = FontFamily::parse(input)?;
Ok(Longhands {
Ok(expanded! {
% for name in "style weight stretch size variant_caps".split():
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
% endfor
@ -236,7 +236,7 @@
if count == 0 || count > 1 {
return Err(())
}
Ok(Longhands {
Ok(expanded! {
font_variant_caps: unwrap_or_initial!(font_variant_caps, caps),
// FIXME: Bug 1356134 - parse all sub properties.
% if product == "gecko" or data.testing:

View file

@ -13,7 +13,7 @@
use parser::Parse;
let url = UrlOrNone::parse(context, input)?;
Ok(Longhands {
Ok(expanded! {
marker_start: url.clone(),
marker_mid: url.clone(),
marker_end: url,

View file

@ -29,7 +29,7 @@
break
}
if color.is_some() || style.is_some() {
Ok(Longhands {
Ok(expanded! {
text_emphasis_color: unwrap_or_initial!(text_emphasis_color, color),
text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style),
})
@ -77,7 +77,7 @@
}
if color.is_some() || width.is_some() {
Ok(Longhands {
Ok(expanded! {
_webkit_text_stroke_color: unwrap_or_initial!(_webkit_text_stroke_color, color),
_webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width),
})

View file

@ -70,35 +70,35 @@
// long as we parsed something.
match (any, nones, list_style_type, image) {
(true, 2, None, None) => {
Ok(Longhands {
Ok(expanded! {
list_style_position: position,
list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)),
list_style_type: list_style_type_none(),
})
}
(true, 1, None, Some(image)) => {
Ok(Longhands {
Ok(expanded! {
list_style_position: position,
list_style_image: image,
list_style_type: list_style_type_none(),
})
}
(true, 1, Some(list_style_type), None) => {
Ok(Longhands {
Ok(expanded! {
list_style_position: position,
list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)),
list_style_type: list_style_type,
})
}
(true, 1, None, None) => {
Ok(Longhands {
Ok(expanded! {
list_style_position: position,
list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)),
list_style_type: list_style_type_none(),
})
}
(true, 0, list_style_type, image) => {
Ok(Longhands {
Ok(expanded! {
list_style_position: position,
list_style_image: unwrap_or_initial!(list_style_image, image),
list_style_type: unwrap_or_initial!(list_style_type),

View file

@ -107,7 +107,7 @@
}
}));
Ok(Longhands {
Ok(expanded! {
% for name in "image mode position_x position_y size repeat origin clip composite".split():
mask_${name}: mask_${name},
% endfor
@ -196,7 +196,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
mask_position_x: position_x,
mask_position_y: position_y,
})

View file

@ -41,7 +41,7 @@
break
}
if any {
Ok(Longhands {
Ok(expanded! {
outline_color: unwrap_or_initial!(outline_color, color),
outline_style: unwrap_or_initial!(outline_style, style),
outline_width: unwrap_or_initial!(outline_width, width),
@ -73,7 +73,7 @@
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
// Re-use border-radius parsing.
shorthands::border_radius::parse_value(context, input).map(|longhands| {
Longhands {
expanded! {
% for corner in ["top_left", "top_right", "bottom_right", "bottom_left"]:
_moz_outline_radius_${corner.replace("_", "")}: longhands.border_${corner}_radius,
% endfor

View file

@ -30,7 +30,7 @@
if direction.is_none() && wrap.is_none() {
return Err(())
}
Ok(Longhands {
Ok(expanded! {
flex_direction: unwrap_or_initial!(flex_direction, direction),
flex_wrap: unwrap_or_initial!(flex_wrap, wrap),
})
@ -63,7 +63,7 @@
let mut basis = None;
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(Longhands {
return Ok(expanded! {
flex_grow: Number::new(0.0),
flex_shrink: Number::new(0.0),
flex_basis: longhands::flex_basis::SpecifiedValue::auto(),
@ -89,7 +89,7 @@
if grow.is_none() && basis.is_none() {
return Err(())
}
Ok(Longhands {
Ok(expanded! {
flex_grow: grow.unwrap_or(Number::new(1.0)),
flex_shrink: shrink.unwrap_or(Number::new(1.0)),
flex_basis: basis.unwrap_or(longhands::flex_basis::SpecifiedValue::zero()),
@ -118,7 +118,7 @@
let row_gap = grid_row_gap::parse(context, input)?;
let column_gap = input.try(|input| grid_column_gap::parse(context, input)).unwrap_or(row_gap.clone());
Ok(Longhands {
Ok(expanded! {
grid_row_gap: row_gap,
grid_column_gap: column_gap,
})
@ -161,7 +161,7 @@
line
};
Ok(Longhands {
Ok(expanded! {
grid_${kind}_start: start,
grid_${kind}_end: end,
})
@ -219,7 +219,7 @@
(line.clone(), line.clone(), line)
};
Ok(Longhands {
Ok(expanded! {
grid_row_start: row_start,
grid_row_end: row_end,
grid_column_start: column_start,
@ -258,7 +258,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
align_content: align,
justify_content: justify,
})
@ -292,7 +292,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
align_self: align,
justify_self: justify,
})
@ -334,7 +334,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
align_items: align,
justify_items: justify,
})

View file

@ -50,7 +50,7 @@
return Err(());
}
Ok(Longhands {
Ok(expanded! {
text_decoration_line: unwrap_or_initial!(text_decoration_line, line),
% if product == "gecko" or data.testing:

View file

@ -4,22 +4,34 @@
use parsing::parse;
use style::parser::Parse;
use style::properties::MaybeBoxed;
use style::properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
use style::properties::longhands::{border_image_source, border_image_width};
use style::properties::shorthands::border_image;
use style_traits::ToCss;
macro_rules! assert_longhand {
($parsed_shorthand: expr, $prop: ident, $value_string: expr) => {
assert_eq!($parsed_shorthand.$prop, parse_longhand!($prop, $value_string).maybe_boxed())
}
}
macro_rules! assert_initial {
($parsed_shorthand: expr, $prop: ident) => {
assert_eq!($parsed_shorthand.$prop, $prop::get_initial_specified_value().maybe_boxed())
}
}
#[test]
fn border_image_shorthand_should_parse_when_all_properties_specified() {
let input = "linear-gradient(red, blue) 30 30% 45 fill / 20px 40px / 10px round stretch";
let result = parse(border_image::parse_value, input).unwrap();
assert_eq!(result.border_image_source,
parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill"));
assert_eq!(result.border_image_width, parse_longhand!(border_image_width, "20px 40px"));
assert_eq!(result.border_image_outset, parse_longhand!(border_image_outset, "10px"));
assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round stretch"));
assert_longhand!(result, border_image_source, "linear-gradient(red, blue)");
assert_longhand!(result, border_image_slice, "30 30% 45 fill");
assert_longhand!(result, border_image_width, "20px 40px");
assert_longhand!(result, border_image_outset, "10px");
assert_longhand!(result, border_image_repeat, "round stretch");
}
#[test]
@ -27,12 +39,11 @@ fn border_image_shorthand_should_parse_without_width() {
let input = "linear-gradient(red, blue) 30 30% 45 fill / / 10px round stretch";
let result = parse(border_image::parse_value, input).unwrap();
assert_eq!(result.border_image_source,
parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill"));
assert_eq!(result.border_image_outset, parse_longhand!(border_image_outset, "10px"));
assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round stretch"));
assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value());
assert_longhand!(result, border_image_source, "linear-gradient(red, blue)");
assert_longhand!(result, border_image_slice, "30 30% 45 fill");
assert_longhand!(result, border_image_outset, "10px");
assert_longhand!(result, border_image_repeat, "round stretch");
assert_initial!(result, border_image_width);
}
#[test]
@ -40,12 +51,11 @@ fn border_image_shorthand_should_parse_without_outset() {
let input = "linear-gradient(red, blue) 30 30% 45 fill / 20px 40px round";
let result = parse(border_image::parse_value, input).unwrap();
assert_eq!(result.border_image_source,
parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill"));
assert_eq!(result.border_image_width, parse_longhand!(border_image_width, "20px 40px"));
assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round"));
assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value());
assert_longhand!(result, border_image_source, "linear-gradient(red, blue)");
assert_longhand!(result, border_image_slice, "30 30% 45 fill");
assert_longhand!(result, border_image_width, "20px 40px");
assert_longhand!(result, border_image_repeat, "round");
assert_initial!(result, border_image_outset);
}
#[test]
@ -53,24 +63,22 @@ fn border_image_shorthand_should_parse_without_width_or_outset() {
let input = "linear-gradient(red, blue) 30 30% 45 fill round";
let result = parse(border_image::parse_value, input).unwrap();
assert_eq!(result.border_image_source,
parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill"));
assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round"));
assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value());
assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value());
assert_longhand!(result, border_image_source, "linear-gradient(red, blue)");
assert_longhand!(result, border_image_slice, "30 30% 45 fill");
assert_longhand!(result, border_image_repeat, "round");
assert_initial!(result, border_image_width);
assert_initial!(result, border_image_outset);
}
#[test]
fn border_image_shorthand_should_parse_with_just_source() {
let result = parse(border_image::parse_value, "linear-gradient(red, blue)").unwrap();
assert_eq!(result.border_image_source,
parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
assert_eq!(result.border_image_slice, border_image_slice::get_initial_specified_value());
assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value());
assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value());
assert_eq!(result.border_image_repeat, border_image_repeat::get_initial_specified_value());
assert_longhand!(result, border_image_source, "linear-gradient(red, blue)");
assert_initial!(result, border_image_slice);
assert_initial!(result, border_image_width);
assert_initial!(result, border_image_outset);
assert_initial!(result, border_image_repeat);
}
#[test]

View file

@ -5,7 +5,7 @@
use style::properties;
size_of_test!(test_size_of_property_declaration, properties::PropertyDeclaration, 32);
size_of_test!(test_size_of_parsed_declaration, properties::ParsedDeclaration, 456);
size_of_test!(test_size_of_parsed_declaration, properties::ParsedDeclaration, 272);
#[test]
fn size_of_specified_values() {

View file

@ -20,7 +20,7 @@ fn size_of_selectors_dummy_types() {
}
size_of_test!(test_size_of_property_declaration, style::properties::PropertyDeclaration, 32);
size_of_test!(test_size_of_parsed_declaration, style::properties::ParsedDeclaration, 584);
size_of_test!(test_size_of_parsed_declaration, style::properties::ParsedDeclaration, 400);
#[test]
fn size_of_specified_values() {