Permalink
Browse files

style: Derive more length stuff, and shrink MaxLength / MozLength's r…

…epr(C) representation.

This patch:

 * Makes LengthPercentageOrAuto generic, and removes a bunch of code fo
   LengthPercentageOrNone, which was used only for servo and now can use the
   normal MaxLength (with a cfg() guard for the ExtremumLength variant).

 * Shrinks MaxLength / MozLength's repr(C) reperesentation by reducing enum
   nesting. The shrinking is in preparation for using them from C++ too, though
   that'd be a different bug.

 * Moves NonNegative usage to the proper places so that stuff for them can be
   derived.

I did this on top of bug 1523071 to prove both that it could be possible and
that stuff wasn't too messy. It got a bit messy, but just because of a bug I
had fixed in bindgen long time ago already, so this updates bindgen's patch
version to grab a fix instead of ugly workarounds :)

Differential Revision: https://phabricator.services.mozilla.com/D17762
  • Loading branch information...
emilio committed Jan 27, 2019
1 parent 8dad956 commit a68bc29b96ac1c42d3940434c6c3239ee0f42a7a
@@ -99,7 +99,7 @@ item_types = ["enums", "structs", "typedefs"]
template<typename T> inline nscoord ResolveWith(T aPercentageGetter) const;
"""

"LengthPercentageOrAuto" = """
"GenericLengthPercentageOrAuto" = """
inline const StyleLengthPercentage& AsLengthPercentage() const;
inline bool HasPercent() const;
inline bool ConvertsToLength() const;
@@ -27,6 +27,7 @@ use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentag
use crate::values::generics::box_::VerticalAlign;
use crate::values::generics::grid::{TrackListValue, TrackSize};
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto;
use crate::values::generics::rect::Rect;
use crate::values::generics::NonNegative;
use app_units::Au;
@@ -62,27 +63,27 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage {
}
}

impl LengthPercentageOrAuto {
impl NonNegativeLengthPercentageOrAuto {
/// Convert this value in an appropriate `nsStyleCoord::CalcValue`.
pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> {
match *self {
LengthPercentageOrAuto::LengthPercentage(len) => Some(From::from(len)),
LengthPercentageOrAuto::Auto => None,
GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)),
GenericLengthPercentageOrAuto::Auto => None,
}
}
}

impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto {
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other))
GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other))
}
}

// FIXME(emilio): A lot of these impl From should probably become explicit or
// disappear as we move more stuff to cbindgen.
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> Self {
NonNegative(LengthPercentageOrAuto::LengthPercentage(
GenericLengthPercentageOrAuto::LengthPercentage(NonNegative(
LengthPercentage::with_clamping_mode(
Au(other.mLength).into(),
if other.mHasPercent {
@@ -14,15 +14,15 @@ use crate::media_queries::Device;
use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use crate::values::computed::FlexBasis as ComputedFlexBasis;
use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage};
use crate::values::computed::{LengthPercentageOrAuto, Percentage};
use crate::values::computed::{LengthPercentageOrNone, Number, NumberOrPercentage};
use crate::values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength};
use crate::values::computed::{NonNegativeLengthPercentage, Percentage};
use crate::values::computed::{Number, NumberOrPercentage};
use crate::values::generics::basic_shape::ShapeRadius;
use crate::values::generics::box_::Perspective;
use crate::values::generics::flex::FlexBasis;
use crate::values::generics::gecko::ScrollSnapPoint;
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
use crate::values::generics::length::{MaxLength, MozLength};
use crate::values::generics::length::{LengthPercentageOrAuto, MaxLength, MozLength};
use crate::values::generics::{CounterStyleOrNone, NonNegative};
use crate::values::{Auto, Either, None_, Normal};
use crate::Atom;
@@ -183,7 +183,10 @@ impl GeckoStyleCoordConvertible for Length {
}
}

impl GeckoStyleCoordConvertible for LengthPercentageOrAuto {
impl<LengthPercentage> GeckoStyleCoordConvertible for LengthPercentageOrAuto<LengthPercentage>
where
LengthPercentage: GeckoStyleCoordConvertible,
{
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto),
@@ -200,23 +203,6 @@ impl GeckoStyleCoordConvertible for LengthPercentageOrAuto {
}
}

impl GeckoStyleCoordConvertible for LengthPercentageOrNone {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
LengthPercentageOrNone::None => coord.set_value(CoordDataValue::None),
LengthPercentageOrNone::LengthPercentage(ref lp) => lp.to_gecko_style_coord(coord),
}
}

fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::None => Some(LengthPercentageOrNone::None),
_ => LengthPercentage::from_gecko_style_coord(coord)
.map(LengthPercentageOrNone::LengthPercentage),
}
}
}

impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<L> {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
@@ -367,34 +353,40 @@ impl GeckoStyleCoordConvertible for ExtremumLength {
impl GeckoStyleCoordConvertible for ComputedMozLength {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
MozLength::LengthPercentageOrAuto(ref lpoa) => lpoa.to_gecko_style_coord(coord),
MozLength::LengthPercentage(ref lpoa) => lpoa.to_gecko_style_coord(coord),
MozLength::Auto => coord.set_value(CoordDataValue::Auto),
MozLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
}
}

fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
LengthPercentageOrAuto::from_gecko_style_coord(coord)
.map(MozLength::LengthPercentageOrAuto)
.or_else(|| {
ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength)
})
if let CoordDataValue::Auto = coord.as_value() {
return Some(MozLength::Auto);
}
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
return Some(MozLength::LengthPercentage(lp));
}
ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength)
}
}

impl GeckoStyleCoordConvertible for ComputedMaxLength {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
MaxLength::LengthPercentageOrNone(ref lpon) => lpon.to_gecko_style_coord(coord),
MaxLength::LengthPercentage(ref lpon) => lpon.to_gecko_style_coord(coord),
MaxLength::None => coord.set_value(CoordDataValue::None),
MaxLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord),
}
}

fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
LengthPercentageOrNone::from_gecko_style_coord(coord)
.map(MaxLength::LengthPercentageOrNone)
.or_else(|| {
ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength)
})
if let CoordDataValue::None = coord.as_value() {
return Some(MaxLength::None);
}
if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) {
return Some(MaxLength::LengthPercentage(lp));
}
ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength)
}
}

@@ -1390,7 +1390,6 @@ impl Clone for ${style_struct.gecko_struct_name} {
"LengthOrNormal": impl_style_coord,
"LengthPercentage": impl_simple,
"LengthPercentageOrAuto": impl_style_coord,
"LengthPercentageOrNone": impl_style_coord,
"MaxLength": impl_style_coord,
"MozLength": impl_style_coord,
"MozScriptMinSize": impl_absolute_length,
@@ -3831,11 +3830,11 @@ fn static_assert() {
BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => {
let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto;
let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto;
if let Some(w) = explicit_width.0.to_calc_value() {
if let Some(w) = explicit_width.to_calc_value() {
width = w;
w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
}
if let Some(h) = explicit_height.0.to_calc_value() {
if let Some(h) = explicit_height.to_calc_value() {
height = h;
h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage;
}
@@ -13,7 +13,7 @@
${helpers.predefined_type(
side,
"LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto",
"computed::LengthPercentageOrAuto::auto()",
spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
flags="GETCS_NEEDS_LAYOUT_FLUSH",
animation_value_type="ComputedValue",
@@ -27,7 +27,7 @@
${helpers.predefined_type(
"inset-%s" % side,
"LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto",
"computed::LengthPercentageOrAuto::auto()",
spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side,
flags="GETCS_NEEDS_LAYOUT_FLUSH",
alias="offset-%s:layout.css.offset-logical-properties.enabled" % side,
@@ -270,24 +270,12 @@ ${helpers.predefined_type(
animation_value_type="MozLength",
servo_restyle_damage="reflow",
)}
${helpers.predefined_type(
"max-%s" % size,
"MaxLength",
"computed::MaxLength::none()",
logical=logical,
logical_group="max-size",
allow_quirks=not logical,
spec=spec % size,
animation_value_type="MaxLength",
servo_restyle_damage="reflow",
)}
% else:
// servo versions (no keyword support)
${helpers.predefined_type(
size,
"LengthPercentageOrAuto",
"computed::LengthPercentageOrAuto::Auto",
"parse_non_negative",
"NonNegativeLengthPercentageOrAuto",
"computed::NonNegativeLengthPercentageOrAuto::auto()",
spec=spec % size,
logical_group="size",
allow_quirks=not logical,
@@ -296,29 +284,27 @@ ${helpers.predefined_type(
)}
${helpers.predefined_type(
"min-%s" % size,
"LengthPercentage",
"computed::LengthPercentage::zero()",
"parse_non_negative",
"NonNegativeLengthPercentage",
"computed::NonNegativeLengthPercentage::zero()",
spec=spec % ("min-%s" % size),
logical_group="min-size",
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical,
servo_restyle_damage="reflow",
)}
${helpers.predefined_type(
"max-%s" % size,
"LengthPercentageOrNone",
"computed::LengthPercentageOrNone::None",
"parse_non_negative",
spec=spec % ("max-%s" % size),
logical_group="max-size",
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical,
servo_restyle_damage="reflow",
)}
% endif
${helpers.predefined_type(
"max-%s" % size,
"MaxLength",
"computed::MaxLength::none()",
logical=logical,
logical_group="max-size",
allow_quirks=not logical,
spec=spec % size,
animation_value_type="MaxLength",
servo_restyle_damage="reflow",
)}
% endfor

${helpers.single_keyword(
@@ -3016,7 +3016,7 @@ impl ComputedValuesInner {

/// Get the logical computed inline size.
#[inline]
pub fn content_inline_size(&self) -> computed::LengthPercentageOrAuto {
pub fn content_inline_size(&self) -> computed::NonNegativeLengthPercentageOrAuto {
let position_style = self.get_position();
if self.writing_mode.is_vertical() {
position_style.height
@@ -3027,35 +3027,35 @@ impl ComputedValuesInner {

/// Get the logical computed block size.
#[inline]
pub fn content_block_size(&self) -> computed::LengthPercentageOrAuto {
pub fn content_block_size(&self) -> computed::NonNegativeLengthPercentageOrAuto {
let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.width } else { position_style.height }
}

/// Get the logical computed min inline size.
#[inline]
pub fn min_inline_size(&self) -> computed::LengthPercentage {
pub fn min_inline_size(&self) -> computed::NonNegativeLengthPercentage {
let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width }
}

/// Get the logical computed min block size.
#[inline]
pub fn min_block_size(&self) -> computed::LengthPercentage {
pub fn min_block_size(&self) -> computed::NonNegativeLengthPercentage {
let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height }
}

/// Get the logical computed max inline size.
#[inline]
pub fn max_inline_size(&self) -> computed::LengthPercentageOrNone {
pub fn max_inline_size(&self) -> computed::MaxLength {
let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width }
}

/// Get the logical computed max block size.
#[inline]
pub fn max_block_size(&self) -> computed::LengthPercentageOrNone {
pub fn max_block_size(&self) -> computed::MaxLength {
let position_style = self.get_position();
if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height }
}
@@ -11,16 +11,17 @@ use crate::context::QuirksMode;
use crate::error_reporting::ContextualParseError;
use crate::font_metrics::get_metrics_provider_for_product;
use crate::media_queries::Device;
use crate::parser::ParserContext;
use crate::parser::{Parse, ParserContext};
use crate::properties::StyleBuilder;
use crate::rule_cache::RuleCacheConditions;
use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
use crate::str::CssStringWriter;
use crate::stylesheets::{Origin, StylesheetInDocument};
use crate::values::computed::{Context, ToComputedValue};
use crate::values::specified::{
self, LengthPercentageOrAuto, NoCalcLength, ViewportPercentageLength,
};
use crate::values::generics::length::LengthPercentageOrAuto;
use crate::values::generics::NonNegative;
use crate::values::specified::{self, NoCalcLength};
use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercentageLength};
use app_units::Au;
use cssparser::CowRcStr;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
@@ -151,17 +152,17 @@ trait FromMeta: Sized {
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)]
pub enum ViewportLength {
Specified(LengthPercentageOrAuto),
Specified(NonNegativeLengthPercentageOrAuto),
ExtendToZoom,
}

impl FromMeta for ViewportLength {
fn from_meta(value: &str) -> Option<ViewportLength> {
macro_rules! specified {
($value:expr) => {
ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(
ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative(
specified::LengthPercentage::Length($value),
))
)))
};
}

@@ -188,7 +189,7 @@ impl ViewportLength {
) -> Result<Self, ParseError<'i>> {
// we explicitly do not accept 'extend-to-zoom', since it is a UA
// internal value for <META> viewport translation
LengthPercentageOrAuto::parse_non_negative(context, input).map(ViewportLength::Specified)
NonNegativeLengthPercentageOrAuto::parse(context, input).map(ViewportLength::Specified)
}
}

Oops, something went wrong.

0 comments on commit a68bc29

Please sign in to comment.