From 0b9ff576e0ad35c75440ea4953b28fef7f5af4df Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 19 Jan 2017 17:13:35 +0100 Subject: [PATCH] script codegen: Avoid modifying in-place a generated file. --- Cargo.lock | 1 + components/script/Cargo.toml | 2 +- components/script/build.rs | 34 +++++++------------ .../dom/bindings/codegen/CodegenRust.py | 25 ++++++++------ .../script/dom/bindings/codegen/GlobalGen.py | 1 + 5 files changed, 29 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20d6d73428a..0733fe31568 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2299,6 +2299,7 @@ dependencies = [ "script_traits 0.0.1", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", "servo_config 0.0.1", "servo_geometry 0.0.1", diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 559ee596a45..4f13003b7f2 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -18,7 +18,7 @@ debugmozjs = ['js/debugmozjs'] cmake = "0.1" phf_codegen = "0.7.18" phf_shared = "0.7.18" -regex = "0.2" +serde_json = "0.8" [target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] tinyfiledialogs = "2.5.9" diff --git a/components/script/build.rs b/components/script/build.rs index 389468f226c..189ce765e01 100644 --- a/components/script/build.rs +++ b/components/script/build.rs @@ -5,13 +5,13 @@ extern crate cmake; extern crate phf_codegen; extern crate phf_shared; -extern crate regex; +extern crate serde_json; -use regex::Regex; +use serde_json::Value; use std::env; use std::fmt; use std::fs::File; -use std::io::{Read, Write}; +use std::io::Write; use std::path::PathBuf; use std::time::Instant; @@ -44,27 +44,17 @@ fn main() { println!("Binding generation completed in {}s", start.elapsed().as_secs()); - convert_phf(); -} - -fn convert_phf() { - let filename = PathBuf::from(env::var("OUT_DIR").unwrap()).join("InterfaceObjectMap.rs"); - let mut source = String::new(); - File::open(&filename).unwrap().read_to_string(&mut source).unwrap(); - let map_macro = Regex::new("phf_map! \\{([^}]+)\\}").unwrap().captures(&source).unwrap(); - let entries_re = Regex::new("b\"([^\"]+)\" => ([^\n]+),\n").unwrap(); - let entries = entries_re.captures_iter(&map_macro[1]); - + let json = PathBuf::from(env::var("OUT_DIR").unwrap()).join("build").join("InterfaceObjectMapData.json"); + let json: Value = serde_json::from_reader(File::open(&json).unwrap()).unwrap(); let mut map = phf_codegen::Map::new(); - for entry in entries { - map.entry(Bytes(entry.get(1).unwrap().as_str()), entry.get(2).unwrap().as_str()); + for (key, value) in json.as_object().unwrap() { + map.entry(Bytes(key), value.as_str().unwrap()); } - - let mut file = File::create(&filename).unwrap(); - let map_macro = map_macro.get(0).unwrap(); - file.write_all(source[..map_macro.start()].as_bytes()).unwrap(); - map.build(&mut file).unwrap(); - file.write_all(source[map_macro.end()..].as_bytes()).unwrap(); + let phf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("InterfaceObjectMapPhf.rs"); + let mut phf = File::create(&phf).unwrap(); + write!(&mut phf, "pub static MAP: phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)> = ").unwrap(); + map.build(&mut phf).unwrap(); + write!(&mut phf, ";\n").unwrap(); } #[derive(Eq, PartialEq, Hash)] diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index f531937d05e..2994734751e 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -6815,6 +6815,15 @@ class GlobalGenRoots(): ], "\n")), pre="pub flags Globals: u8 {\n", post="\n}") globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}") + phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));") + + return CGList([ + CGGeneric(AUTOGENERATED_WARNING_COMMENT), + CGList([imports, globals_, phf], "\n\n") + ]) + + @staticmethod + def InterfaceObjectMapData(config): pairs = [] for d in config.getDescriptors(hasInterfaceObject=True, isInline=False): binding = toBindingNamespace(d.name) @@ -6823,19 +6832,13 @@ class GlobalGenRoots(): pairs.append((ctor.identifier.name, binding, binding)) pairs.sort(key=operator.itemgetter(0)) mappings = [ - CGGeneric('b"%s" => codegen::Bindings::%s::%s::DefineDOMInterface as unsafe fn(_, _),' % pair) + CGGeneric('"%s": "codegen::Bindings::%s::%s::DefineDOMInterface as unsafe fn(_, _)"' % pair) for pair in pairs ] - mapType = "phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)>" - phf = CGWrapper( - CGIndenter(CGList(mappings, "\n")), - pre="pub static MAP: %s = phf_map! {\n" % mapType, - post="\n};\n") - - return CGList([ - CGGeneric(AUTOGENERATED_WARNING_COMMENT), - CGList([imports, globals_, phf], "\n\n") - ]) + return CGWrapper( + CGList(mappings, ",\n"), + pre="{\n", + post="\n}\n") @staticmethod def PrototypeList(config): diff --git a/components/script/dom/bindings/codegen/GlobalGen.py b/components/script/dom/bindings/codegen/GlobalGen.py index 8f122f52bd1..966e4bdbcd2 100644 --- a/components/script/dom/bindings/codegen/GlobalGen.py +++ b/components/script/dom/bindings/codegen/GlobalGen.py @@ -76,6 +76,7 @@ def main(): ('PrototypeList', 'PrototypeList.rs'), ('RegisterBindings', 'RegisterBindings.rs'), ('InterfaceObjectMap', 'InterfaceObjectMap.rs'), + ('InterfaceObjectMapData', 'InterfaceObjectMapData.json'), ('InterfaceTypes', 'InterfaceTypes.rs'), ('InheritTypes', 'InheritTypes.rs'), ('Bindings', os.path.join('Bindings', 'mod.rs')),