Skip to content

Commit

Permalink
servo: Merge #10749 - Prepare related files to make it easier to spli…
Browse files Browse the repository at this point in the history
…t up the Mako template (from servo:split-mako); r=nox

servo/servo#10586 (comment)

r? nox

Source-Repo: https://github.com/servo/servo
Source-Revision: 3bfa4cc7414fea760ce5c503bfbcf25262acb9d7

UltraBlame original commit: 75af6f5e3e2d5876694d389cfcaf04de2120ab6e
  • Loading branch information
marco-c committed Oct 1, 2019
1 parent 8cb38f3 commit be66e43
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 381 deletions.
29 changes: 9 additions & 20 deletions servo/components/style/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@


use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Stdio, exit};
use std::process::{Command, exit};

#[cfg(windows)]
fn find_python() -> String {
Expand All @@ -31,25 +29,16 @@ fn find_python() -> String {
}

fn main() {
let python = match env::var("PYTHON") {
Ok(python_path) => python_path,
Err(_) => find_python(),
};
let style = Path::new(file!()).parent().unwrap();
let mako = style.join("Mako-0.9.1.zip");
let template = style.join("properties.mako.rs");
let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
let script = Path::new(file!()).parent().unwrap().join("properties").join("build.py");
let product = if cfg!(feature = "gecko") { "gecko" } else { "servo" };
let result = Command::new(python)
.env("PYTHONPATH", &mako)
.env("TEMPLATE", &template)
.env("PRODUCT", product)
.arg("generate_properties_rs.py")
.stderr(Stdio::inherit())
.output()
let status = Command::new(python)
.arg(&script)
.arg(product)
.arg("style-crate")
.status()
.unwrap();
if !result.status.success() {
if !status.success() {
exit(1)
}
let out = env::var("OUT_DIR").unwrap();
File::create(&Path::new(&out).join("properties.rs")).unwrap().write_all(&result.stdout).unwrap();
}
17 changes: 0 additions & 17 deletions servo/components/style/generate_properties_rs.py

This file was deleted.

41 changes: 0 additions & 41 deletions servo/components/style/list_properties.py

This file was deleted.

File renamed without changes.
80 changes: 80 additions & 0 deletions servo/components/style/properties/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@




import json
import os.path
import sys

BASE = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(BASE, "Mako-0.9.1.zip"))

from mako import exceptions
from mako.template import Template

import data


def main():
usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib | html ]" % sys.argv[0]
if len(sys.argv) < 3:
abort(usage)
product = sys.argv[1]
output = sys.argv[2]
if product not in ["servo", "gecko"] or output not in ["style-crate", "geckolib", "html"]:
abort(usage)

properties = data.PropertiesData(product=product)
rust = render(os.path.join(BASE, "properties.mako.rs"), product=product, data=properties)
if output == "style-crate":
write(os.environ["OUT_DIR"], "properties.rs", rust)
if output == "geckolib":
template = os.path.join(BASE, "..", "..", "..", "ports", "geckolib", "properties.mako.rs")
rust = render(template, data=properties)
write(os.environ["OUT_DIR"], "properties.rs", rust)
elif output == "html":
write_html(properties)


def abort(message):
sys.stderr.write(message + b"\n")
sys.exit(1)


def render(filename, **context):
try:
template = Template(open(filename, "rb").read(),
input_encoding="utf8",
strict_undefined=True,
filename=filename)


return template.render(**context).encode("utf8")
except:


abort(exceptions.text_error_template().render().encode("utf8"))


def write(directory, filename, content):
if not os.path.exists(directory):
os.makedirs(directory)
open(os.path.join(directory, filename), "wb").write(content)


def write_html(properties):
properties = dict(
(p.name, {
"flag": p.experimental,
"shorthand": hasattr(p, "sub_properties")
})
for p in properties.longhands + properties.shorthands
)
doc_servo = os.path.join(BASE, "..", "..", "..", "target", "doc", "servo")
html = render(os.path.join(BASE, "properties.html.mako"), properties=properties)
write(doc_servo, "css-properties.html", html)
write(doc_servo, "css-properties.json", json.dumps(properties, indent=4))


if __name__ == "__main__":
main()
156 changes: 156 additions & 0 deletions servo/components/style/properties/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@




import re


def to_rust_ident(name):
name = name.replace("-", "_")
if name in ["static", "super", "box", "move"]:
name += "_"
return name


def to_camel_case(ident):
return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize())


class Keyword(object):
def __init__(self, name, values, gecko_constant_prefix=None,
extra_gecko_values=None, extra_servo_values=None):
self.name = name
self.values = values
self.gecko_constant_prefix = gecko_constant_prefix or \
"NS_STYLE_" + self.name.upper().replace("-", "_")
self.extra_gecko_values = (extra_gecko_values or "").split()
self.extra_servo_values = (extra_servo_values or "").split()

def gecko_values(self):
return self.values + self.extra_gecko_values

def servo_values(self):
return self.values + self.extra_servo_values

def values_for(self, product):
if product == "gecko":
return self.gecko_values()
elif product == "servo":
return self.servo_values()
else:
raise Exception("Bad product: " + product)

def gecko_constant(self, value):
return self.gecko_constant_prefix + "_" + value.upper().replace("-", "_")


class Longhand(object):
def __init__(self, style_struct, name, derived_from=None, keyword=None,
custom_cascade=False, experimental=False, internal=False,
gecko_ffi_name=None):
self.name = name
self.keyword = keyword
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.style_struct = style_struct
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.custom_cascade = custom_cascade
self.internal = internal
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
self.derived_from = (derived_from or "").split()


class Shorthand(object):
def __init__(self, name, sub_properties, experimental=False, internal=False):
self.name = name
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.derived_from = None
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.sub_properties = sub_properties
self.internal = internal


class Method(object):
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
self.name = name
self.return_type = return_type
self.arg_types = arg_types or []
self.is_mut = is_mut

def arg_list(self):
args = ["_: " + x for x in self.arg_types]
args = ["&mut self" if self.is_mut else "&self"] + args
return ", ".join(args)

def signature(self):
sig = "fn %s(%s)" % (self.name, self.arg_list())
if self.return_type:
sig = sig + " -> " + self.return_type
return sig

def declare(self):
return self.signature() + ";"

def stub(self):
return self.signature() + "{ unimplemented!() }"


class StyleStruct(object):
def __init__(self, name, inherited, gecko_ffi_name=None, additional_methods=None):
self.servo_struct_name = "Servo" + name
self.gecko_struct_name = "Gecko" + name
self.trait_name = name
self.trait_name_lower = name.lower()
self.ident = to_rust_ident(self.trait_name_lower)
self.longhands = []
self.inherited = inherited
self.gecko_ffi_name = gecko_ffi_name
self.additional_methods = additional_methods or []


class PropertiesData(object):
def __init__(self, product):
self.product = product
self.style_structs = []
self.current_style_struct = None
self.longhands = []
self.longhands_by_name = {}
self.derived_longhands = {}
self.shorthands = []

def new_style_struct(self, *args, **kwargs):
style_struct = StyleStruct(*args, **kwargs)
self.style_structs.append(style_struct)
self.current_style_struct = style_struct

def active_style_structs(self):
return [s for s in self.style_structs if s.additional_methods or s.longhands]

def switch_to_style_struct(self, name):
for style_struct in self.style_structs:
if style_struct.trait_name == name:
self.current_style_struct = style_struct
return
raise Exception("Failed to find the struct named " + name)

def declare_longhand(self, name, products="gecko servo", **kwargs):
products = products.split()
if self.product not in products:
return

longand = Longhand(self.current_style_struct, name, **kwargs)
self.current_style_struct.longhands.append(longand)
self.longhands.append(longand)
self.longhands_by_name[name] = longand

for name in longand.derived_from:
self.derived_longhands.setdefault(name, []).append(longand)

return longand

def declare_shorthand(self, name, sub_properties, *args, **kwargs):
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
self.shorthands.append(shorthand)
return shorthand
File renamed without changes.
Loading

0 comments on commit be66e43

Please sign in to comment.