servo: Merge #19980 - Merge all keyword arms in Clone for PropertyDeclaration 🐉🐲 (from servo:derive-all-the-things); r=emilio

Source-Repo: https://github.com/servo/servo
Source-Revision: 41fb6ed1ffda877c24747a4d209bb32885ac6b2f

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 4fe49db37e4463fa1bd09e6cd1b6cefc11a24530
This commit is contained in:
Anthony Ramine 2018-02-09 16:17:01 -05:00
parent 6be8c9a11a
commit f42317f931
9 changed files with 125 additions and 31 deletions

1
servo/Cargo.lock generated
View File

@ -2885,6 +2885,7 @@ dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
"debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.16.4 (registry+https://github.com/rust-lang/crates.io-index)",
"fallible 0.0.1",

View File

@ -32,6 +32,7 @@ bitflags = "1.0"
byteorder = "1.0"
cfg-if = "0.1.0"
cssparser = "0.23.0"
debug_unreachable = "0.1.1"
encoding_rs = {version = "0.7", optional = true}
euclid = "0.16"
fallible = { path = "../fallible" }

View File

@ -33,6 +33,7 @@ extern crate bitflags;
#[allow(unused_extern_crates)] extern crate byteorder;
#[cfg(feature = "gecko")] #[macro_use] #[no_link] extern crate cfg_if;
#[macro_use] extern crate cssparser;
#[macro_use] extern crate debug_unreachable;
extern crate euclid;
extern crate fallible;
extern crate fnv;

View File

@ -229,6 +229,58 @@ class Longhand(object):
def enabled_in_content(self):
return self.enabled_in == "content"
def specified_type(self):
if self.predefined_type and not self.is_vector:
ty = "::values::specified::{}".format(self.predefined_type)
else:
ty = "longhands::{}::SpecifiedValue".format(self.ident)
if self.boxed:
ty = "Box<{}>".format(ty)
return ty
def specified_is_copy(self):
if self.is_vector or self.boxed:
return False
if self.predefined_type:
return self.predefined_type in {
"AlignContent",
"AlignItems",
"AlignSelf",
"BackgroundRepeat",
"BorderImageRepeat",
"BorderStyle",
"Contain",
"FontStyleAdjust",
"FontSynthesis",
"FontWeight",
"GridAutoFlow",
"ImageOrientation",
"InitialLetter",
"Integer",
"IntegerOrAuto",
"JustifyContent",
"JustifyItems",
"JustifySelf",
"MozForceBrokenImageIcon",
"MozScriptLevel",
"MozScriptMinSize",
"MozScriptSizeMultiplier",
"NonNegativeNumber",
"Opacity",
"OutlineStyle",
"OverscrollBehavior",
"Percentage",
"PositiveIntegerOrAuto",
"SVGPaintOrder",
"ScrollSnapType",
"TextDecorationLine",
"TouchAction",
"TransformStyle",
"XSpan",
"XTextZoom",
}
return bool(self.keyword)
class Shorthand(object):
def __init__(self, name, sub_properties, spec=None, servo_pref=None, gecko_pref=None,

View File

@ -206,31 +206,35 @@ pub mod animated_properties {
<%
from itertools import groupby
# After this code, `data.longhands` is sorted in the following order:
# - first all keyword variants and all variants known to be Copy,
# - second all the other variants, such as all variants with the same field
# have consecutive discriminants.
# The variable `variants` contain the same entries as `data.longhands` in
# the same order, but must exist separately to the data source, because
# we then need to add three additional variants `WideKeywordDeclaration`,
# `VariableDeclaration` and `CustomDeclaration`.
variants = []
for property in data.longhands:
if property.predefined_type and not property.is_vector:
ty = "::values::specified::{}".format(property.predefined_type)
else:
ty = "longhands::{}::SpecifiedValue".format(property.ident)
if property.boxed:
ty = "Box<{}>".format(ty)
variants.append({
"name": property.camel_case,
"type": ty,
"type": property.specified_type(),
"doc": "`" + property.name + "`",
"copy": property.specified_is_copy(),
})
groups = {}
keyfunc = lambda x: x["type"]
sortkeys = {}
for ty, group in groupby(sorted(variants, key=keyfunc), keyfunc):
group = [v["name"] for v in group]
group = list(group)
groups[ty] = group
for v in group:
if len(group) == 1:
sortkeys[v] = (1, v, "")
sortkeys[v["name"]] = (not v["copy"], 1, v["name"], "")
else:
sortkeys[v] = (len(group), ty, v)
sortkeys[v["name"]] = (not v["copy"], len(group), ty, v["name"])
variants.sort(key=lambda x: sortkeys[x["name"]])
# It is extremely important to sort the `data.longhands` array here so
@ -250,21 +254,24 @@ pub mod animated_properties {
"name": "CSSWideKeyword",
"type": "WideKeywordDeclaration",
"doc": "A CSS-wide keyword.",
"copy": False,
},
{
"name": "WithVariables",
"type": "VariableDeclaration",
"doc": "An unparsed declaration.",
"copy": False,
},
{
"name": "Custom",
"type": "CustomDeclaration",
"doc": "A custom property declaration.",
"copy": False,
},
]
for v in extra:
variants.append(v)
groups[v["type"]] = [v["name"]]
groups[v["type"]] = [v]
%>
/// Servo's representation for a property declaration.
@ -287,14 +294,46 @@ impl Clone for PropertyDeclaration {
fn clone(&self) -> Self {
use self::PropertyDeclaration::*;
<%
[copy, others] = [list(g) for _, g in groupby(variants, key=lambda x: not x["copy"])]
%>
let self_tag = unsafe {
(*(self as *const _ as *const PropertyDeclarationVariantRepr<()>)).tag
};
if self_tag <= LonghandId::${copy[-1]["name"]} as u16 {
#[derive(Clone, Copy)]
#[repr(u16)]
enum CopyVariants {
% for v in copy:
_${v["name"]}(${v["type"]}),
% endfor
}
unsafe {
let mut out = mem::uninitialized();
ptr::write(
&mut out as *mut _ as *mut CopyVariants,
*(self as *const _ as *const CopyVariants),
);
return out;
}
}
match *self {
% for ty, variants in groups.iteritems():
% if len(variants) == 1:
${variants[0]}(ref value) => {
${variants[0]}(value.clone())
${" |\n".join("{}(..)".format(v["name"]) for v in copy)} => {
unsafe { debug_unreachable!() }
}
% for ty, vs in groupby(others, key=lambda x: x["type"]):
<%
vs = list(vs)
%>
% if len(vs) == 1:
${vs[0]["name"]}(ref value) => {
${vs[0]["name"]}(value.clone())
}
% else:
${" | ".join("{}(ref value)".format(v) for v in variants)} => {
${" |\n".join("{}(ref value)".format(v["name"]) for v in vs)} => {
unsafe {
let mut out = ManuallyDrop::new(mem::uninitialized());
ptr::write(
@ -327,8 +366,8 @@ impl PartialEq for PropertyDeclaration {
return false;
}
match *self {
% for ty, variants in groups.iteritems():
${" | ".join("{}(ref this)".format(v) for v in variants)} => {
% for ty, vs in groupby(variants, key=lambda x: x["type"]):
${" |\n".join("{}(ref this)".format(v["name"]) for v in vs)} => {
let other_repr =
&*(other as *const _ as *const PropertyDeclarationVariantRepr<${ty}>);
*this == other_repr.value
@ -346,8 +385,8 @@ impl MallocSizeOf for PropertyDeclaration {
use self::PropertyDeclaration::*;
match *self {
% for ty, variants in groups.iteritems():
${" | ".join("{}(ref value)".format(v) for v in variants)} => {
% for ty, vs in groupby(variants, key=lambda x: x["type"]):
${" | ".join("{}(ref value)".format(v["name"]) for v in vs)} => {
value.size_of(ops)
}
% endfor
@ -365,8 +404,8 @@ impl PropertyDeclaration {
let mut dest = CssWriter::new(dest);
match *self {
% for ty, variants in groups.iteritems():
${" | ".join("{}(ref value)".format(v) for v in variants)} => {
% for ty, vs in groupby(variants, key=lambda x: x["type"]):
${" | ".join("{}(ref value)".format(v["name"]) for v in vs)} => {
value.to_css(&mut dest)
}
% endfor

View File

@ -675,8 +675,8 @@ pub fn get_normalized_vector_and_angle<T: Zero>(
}
}
#[derive(ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq)]
#[derive(ToAnimatedZero, ToComputedValue, ToCss)]
/// A value of the `Rotate` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
@ -689,8 +689,8 @@ pub enum Rotate<Number, Angle> {
Rotate3D(Number, Number, Number, Angle),
}
#[derive(ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq)]
#[derive(ToAnimatedZero, ToComputedValue, ToCss)]
/// A value of the `Scale` property
///
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>

View File

@ -58,7 +58,7 @@ pub enum BackgroundRepeatKeyword {
/// The specified value for the `background-repeat` property.
///
/// https://drafts.csswg.org/css-backgrounds/#the-background-repeat
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
pub enum BackgroundRepeat {
/// `repeat-x`
RepeatX,

View File

@ -186,7 +186,7 @@ pub enum BorderImageRepeatKeyword {
/// The specified value for the `border-image-repeat` property.
///
/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub Option<BorderImageRepeatKeyword>);
impl BorderImageRepeat {

View File

@ -1757,7 +1757,7 @@ impl Parse for FontFeatureSettings {
}
}
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
/// Whether user agents are allowed to synthesize bold or oblique font faces
/// when a font family lacks bold or italic faces
pub struct FontSynthesis {
@ -2035,7 +2035,7 @@ impl Parse for VariationValue<Number> {
}
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
/// text-zoom. Enable if true, disable if false
pub struct XTextZoom(pub bool);
@ -2087,7 +2087,7 @@ impl ToCss for XLang {
}
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, PartialEq, ToCss)]
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
/// Specifies the minimum font size allowed due to changes in scriptlevel.
/// Ref: https://wiki.mozilla.org/MathML:mstyle
pub struct MozScriptMinSize(pub NoCalcLength);