Avoid pattern matching to clone Copy variants of PropertyDeclaration 🐉🐲

This commit is contained in:
Anthony Ramine 2018-02-08 01:22:34 +01:00
parent 335cb4c9f4
commit 5d8e70dc27
5 changed files with 88 additions and 63 deletions

1
Cargo.lock generated
View file

@ -2886,6 +2886,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.0 (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

@ -226,6 +226,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,59 +206,22 @@ pub mod animated_properties {
<%
from itertools import groupby
copyTypes = set([
"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",
])
# 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:
copy = property.predefined_type in copyTypes
ty = "::values::specified::{}".format(property.predefined_type)
else:
copy = bool(property.keyword) and not property.is_vector
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": copy,
"copy": property.specified_is_copy(),
})
groups = {}
@ -335,24 +298,31 @@ impl Clone for 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 {
${" |\n".join("{}(..)".format(v["name"]) for v in copy)} => {
#[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),
);
out
}
unsafe { debug_unreachable!() }
}
% for ty, vs in groupby(others, key=lambda x: x["type"]):
<%