mirror of
https://github.com/servo/servo.git
synced 2025-08-01 19:50:30 +01:00
Move config info from build_gecko.rs to a toml file in gecko.
This commit is contained in:
parent
0b3fd8de76
commit
f123b26e6c
4 changed files with 247 additions and 579 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2852,6 +2852,7 @@ dependencies = [
|
||||||
"smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,7 +14,7 @@ doctest = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gecko = ["nsstring_vendor", "rayon/unstable", "num_cpus", "style_traits/gecko"]
|
gecko = ["nsstring_vendor", "rayon/unstable", "num_cpus", "style_traits/gecko"]
|
||||||
use_bindgen = ["bindgen", "regex"]
|
use_bindgen = ["bindgen", "regex", "toml"]
|
||||||
servo = ["serde", "serde_derive", "heapsize", "heapsize_derive",
|
servo = ["serde", "serde_derive", "heapsize", "heapsize_derive",
|
||||||
"style_traits/servo", "servo_atoms", "servo_config", "html5ever",
|
"style_traits/servo", "servo_atoms", "servo_config", "html5ever",
|
||||||
"cssparser/heapsize", "cssparser/serde", "encoding", "smallvec/heapsizeof",
|
"cssparser/heapsize", "cssparser/serde", "encoding", "smallvec/heapsizeof",
|
||||||
|
@ -69,3 +69,4 @@ log = "0.3"
|
||||||
bindgen = { version = "0.25", optional = true }
|
bindgen = { version = "0.25", optional = true }
|
||||||
regex = {version = "0.2", optional = true}
|
regex = {version = "0.2", optional = true}
|
||||||
walkdir = "1.0"
|
walkdir = "1.0"
|
||||||
|
toml = {version = "0.2.1", optional = true, default-features = false}
|
||||||
|
|
|
@ -10,6 +10,8 @@ extern crate bindgen;
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[cfg(feature = "bindgen")]
|
#[cfg(feature = "bindgen")]
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
#[cfg(feature = "bindgen")]
|
||||||
|
extern crate toml;
|
||||||
extern crate walkdir;
|
extern crate walkdir;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
|
@ -29,18 +29,20 @@ mod common {
|
||||||
mod bindings {
|
mod bindings {
|
||||||
use bindgen::{Builder, CodegenConfig};
|
use bindgen::{Builder, CodegenConfig};
|
||||||
use bindgen::callbacks::{EnumVariantCustomBehavior, EnumVariantValue, ParseCallbacks};
|
use bindgen::callbacks::{EnumVariantCustomBehavior, EnumVariantValue, ParseCallbacks};
|
||||||
use regex::Regex;
|
use regex::{Regex, RegexSet};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashSet, HashMap};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, exit};
|
use std::process::{Command, exit};
|
||||||
|
use std::slice;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use super::common::*;
|
use super::common::*;
|
||||||
use super::super::PYTHON;
|
use super::super::PYTHON;
|
||||||
|
use toml;
|
||||||
|
|
||||||
const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
|
const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
|
||||||
const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs";
|
const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs";
|
||||||
|
@ -60,6 +62,41 @@ mod bindings {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
static ref CONFIG: toml::Table = {
|
||||||
|
let path = PathBuf::from(env::var("MOZ_SRC").unwrap())
|
||||||
|
.join("layout/style/ServoBindings.toml");
|
||||||
|
println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
|
||||||
|
update_last_modified(&path);
|
||||||
|
|
||||||
|
let mut contents = String::new();
|
||||||
|
File::open(path).expect("Failed to open config file")
|
||||||
|
.read_to_string(&mut contents).expect("Failed to read config file");
|
||||||
|
let mut parser = toml::Parser::new(&contents);
|
||||||
|
if let Some(result) = parser.parse() {
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
use std::fmt::Write;
|
||||||
|
let mut reason = String::from("Failed to parse config file:");
|
||||||
|
for err in parser.errors.iter() {
|
||||||
|
let parsed = &contents[..err.lo];
|
||||||
|
write!(&mut reason, "\n* line {} column {}: {}",
|
||||||
|
parsed.lines().count(),
|
||||||
|
parsed.lines().last().map_or(0, |l| l.len()),
|
||||||
|
err).unwrap();
|
||||||
|
}
|
||||||
|
panic!(reason)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static ref TARGET_INFO: HashMap<String, String> = {
|
||||||
|
const TARGET_PREFIX: &'static str = "CARGO_CFG_TARGET_";
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
for (k, v) in env::vars() {
|
||||||
|
if k.starts_with(TARGET_PREFIX) {
|
||||||
|
result.insert(k[TARGET_PREFIX.len()..].to_lowercase(), v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
};
|
||||||
static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap();
|
static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap();
|
||||||
static ref DISTDIR_PATH: PathBuf = {
|
static ref DISTDIR_PATH: PathBuf = {
|
||||||
let path = PathBuf::from(env::var("MOZ_DIST").unwrap());
|
let path = PathBuf::from(env::var("MOZ_DIST").unwrap());
|
||||||
|
@ -73,7 +110,7 @@ mod bindings {
|
||||||
DISTDIR_PATH.join("include/nspr"),
|
DISTDIR_PATH.join("include/nspr"),
|
||||||
];
|
];
|
||||||
static ref ADDED_PATHS: Mutex<HashSet<PathBuf>> = Mutex::new(HashSet::new());
|
static ref ADDED_PATHS: Mutex<HashSet<PathBuf>> = Mutex::new(HashSet::new());
|
||||||
pub static ref LAST_MODIFIED: Mutex<SystemTime> =
|
static ref LAST_MODIFIED: Mutex<SystemTime> =
|
||||||
Mutex::new(get_modified_time(&env::current_exe().unwrap())
|
Mutex::new(get_modified_time(&env::current_exe().unwrap())
|
||||||
.expect("Failed to get modified time of executable"));
|
.expect("Failed to get modified time of executable"));
|
||||||
}
|
}
|
||||||
|
@ -82,17 +119,20 @@ mod bindings {
|
||||||
file.metadata().and_then(|m| m.modified()).ok()
|
file.metadata().and_then(|m| m.modified()).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_last_modified(file: &Path) {
|
||||||
|
let modified = get_modified_time(file).unwrap();
|
||||||
|
let mut last_modified = LAST_MODIFIED.lock().unwrap();
|
||||||
|
*last_modified = cmp::max(modified, *last_modified);
|
||||||
|
}
|
||||||
|
|
||||||
fn search_include(name: &str) -> Option<PathBuf> {
|
fn search_include(name: &str) -> Option<PathBuf> {
|
||||||
for path in SEARCH_PATHS.iter() {
|
for path in SEARCH_PATHS.iter() {
|
||||||
let file = path.join(name);
|
let file = path.join(name);
|
||||||
if !file.is_file() {
|
if file.is_file() {
|
||||||
continue;
|
update_last_modified(&file);
|
||||||
}
|
|
||||||
let modified = get_modified_time(&file).unwrap();
|
|
||||||
let mut last_modified = LAST_MODIFIED.lock().unwrap();
|
|
||||||
*last_modified = cmp::max(modified, *last_modified);
|
|
||||||
return Some(file);
|
return Some(file);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,22 +164,43 @@ mod bindings {
|
||||||
trait BuilderExt {
|
trait BuilderExt {
|
||||||
fn get_initial_builder(build_type: BuildType) -> Builder;
|
fn get_initial_builder(build_type: BuildType) -> Builder;
|
||||||
fn include<T: Into<String>>(self, file: T) -> Builder;
|
fn include<T: Into<String>>(self, file: T) -> Builder;
|
||||||
fn zero_size_type(self, ty: &str, structs_list: &[&str]) -> Builder;
|
fn zero_size_type(self, ty: &str, structs_list: &HashSet<&str>) -> Builder;
|
||||||
fn borrowed_type(self, ty: &str) -> Builder;
|
fn borrowed_type(self, ty: &str) -> Builder;
|
||||||
fn mutable_borrowed_type(self, ty: &str) -> Builder;
|
fn mutable_borrowed_type(self, ty: &str) -> Builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_clang_args(mut builder: Builder, config: &toml::Table, matched_os: &mut bool) -> Builder {
|
||||||
|
fn add_args(mut builder: Builder, values: &[toml::Value]) -> Builder {
|
||||||
|
for item in values.iter() {
|
||||||
|
builder = builder.clang_arg(item.as_str().expect("Expect string in list"));
|
||||||
|
}
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
for (k, v) in config.iter() {
|
||||||
|
if k == "args" {
|
||||||
|
builder = add_args(builder, v.as_slice().unwrap());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let equal_idx = k.find('=').expect(&format!("Invalid key: {}", k));
|
||||||
|
let (target_type, target_value) = k.split_at(equal_idx);
|
||||||
|
if TARGET_INFO[target_type] != target_value[1..] {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if target_type == "os" {
|
||||||
|
*matched_os = true;
|
||||||
|
}
|
||||||
|
builder = match *v {
|
||||||
|
toml::Value::Table(ref table) => add_clang_args(builder, table, matched_os),
|
||||||
|
toml::Value::Array(ref array) => add_args(builder, array),
|
||||||
|
_ => panic!("Unknown type"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
|
||||||
impl BuilderExt for Builder {
|
impl BuilderExt for Builder {
|
||||||
fn get_initial_builder(build_type: BuildType) -> Builder {
|
fn get_initial_builder(build_type: BuildType) -> Builder {
|
||||||
let mut builder = Builder::default().no_unstable_rust();
|
let mut builder = Builder::default().no_unstable_rust();
|
||||||
let args = [
|
|
||||||
"-x", "c++", "-std=c++14",
|
|
||||||
"-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1",
|
|
||||||
"-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN", "-DMOZ_STYLO"
|
|
||||||
];
|
|
||||||
for &arg in args.iter() {
|
|
||||||
builder = builder.clang_arg(arg);
|
|
||||||
}
|
|
||||||
for dir in SEARCH_PATHS.iter() {
|
for dir in SEARCH_PATHS.iter() {
|
||||||
builder = builder.clang_arg("-I").clang_arg(dir.to_str().unwrap());
|
builder = builder.clang_arg("-I").clang_arg(dir.to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
@ -148,63 +209,11 @@ mod bindings {
|
||||||
if build_type == BuildType::Debug {
|
if build_type == BuildType::Debug {
|
||||||
builder = builder.clang_arg("-DDEBUG=1").clang_arg("-DJS_DEBUG=1");
|
builder = builder.clang_arg("-DDEBUG=1").clang_arg("-DJS_DEBUG=1");
|
||||||
}
|
}
|
||||||
// cfg!(...) will check the attributes of the Rust target this file
|
|
||||||
// is being compiled for. We want the attributes of the target that
|
|
||||||
// the clang we're going to invoke is being compiled for, which isn't
|
|
||||||
// necessarily the same thing. Cargo provides the (yet-to-be-documented)
|
|
||||||
// CARGO_CFG_* environment variables for this purpose. Those variables
|
|
||||||
// should be used in preference to cfg! checks below.
|
|
||||||
let target_family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
|
|
||||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
||||||
let target_pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
|
|
||||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
||||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
|
||||||
|
|
||||||
if target_family == "unix" {
|
let mut matched_os = false;
|
||||||
builder = builder.clang_arg("-DOS_POSIX=1");
|
let build_config = CONFIG["build"].as_table().expect("Malformed config file");
|
||||||
}
|
builder = add_clang_args(builder, build_config, &mut matched_os);
|
||||||
if target_os == "linux" {
|
if !matched_os {
|
||||||
builder = builder.clang_arg("-DOS_LINUX=1");
|
|
||||||
if target_arch == "x86" {
|
|
||||||
builder = builder.clang_arg("-m32");
|
|
||||||
} else if target_arch == "x86_64" {
|
|
||||||
builder = builder.clang_arg("-m64");
|
|
||||||
}
|
|
||||||
} else if target_os == "solaris" {
|
|
||||||
builder = builder.clang_arg("-DOS_SOLARIS=1");
|
|
||||||
} else if target_os == "dragonfly" {
|
|
||||||
builder = builder.clang_arg("-DOS_BSD=1").clang_arg("-DOS_DRAGONFLY=1");
|
|
||||||
} else if target_os == "freebsd" {
|
|
||||||
builder = builder.clang_arg("-DOS_BSD=1").clang_arg("-DOS_FREEBSD=1");
|
|
||||||
} else if target_os == "netbsd" {
|
|
||||||
builder = builder.clang_arg("-DOS_BSD=1").clang_arg("-DOS_NETBSD=1");
|
|
||||||
} else if target_os == "openbsd" {
|
|
||||||
builder = builder.clang_arg("-DOS_BSD=1").clang_arg("-DOS_OPENBSD=1");
|
|
||||||
} else if target_os == "macos" {
|
|
||||||
builder = builder.clang_arg("-DOS_MACOSX=1")
|
|
||||||
.clang_arg("-stdlib=libc++")
|
|
||||||
// To disable the fixup bindgen applies which adds search
|
|
||||||
// paths from clang command line in order to avoid potential
|
|
||||||
// conflict with -stdlib=libc++.
|
|
||||||
.clang_arg("--target=x86_64-apple-darwin");
|
|
||||||
} else if target_env == "msvc" {
|
|
||||||
builder = builder.clang_arg("-DOS_WIN=1").clang_arg("-DWIN32=1")
|
|
||||||
// For compatibility with MSVC 2015
|
|
||||||
.clang_arg("-fms-compatibility-version=19")
|
|
||||||
// To enable the builtin __builtin_offsetof so that CRT wouldn't
|
|
||||||
// use reinterpret_cast in offsetof() which is not allowed inside
|
|
||||||
// static_assert().
|
|
||||||
.clang_arg("-D_CRT_USE_BUILTIN_OFFSETOF")
|
|
||||||
// Enable hidden attribute (which is not supported by MSVC and
|
|
||||||
// thus not enabled by default with a MSVC-compatibile build)
|
|
||||||
// to exclude hidden symbols from the generated file.
|
|
||||||
.clang_arg("-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1");
|
|
||||||
if target_pointer_width == "32" {
|
|
||||||
builder = builder.clang_arg("--target=i686-pc-win32");
|
|
||||||
} else {
|
|
||||||
builder = builder.clang_arg("--target=x86_64-pc-win32");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("Unknown platform");
|
panic!("Unknown platform");
|
||||||
}
|
}
|
||||||
builder
|
builder
|
||||||
|
@ -220,8 +229,8 @@ mod bindings {
|
||||||
// Not 100% sure of how safe this is, but it's what we're using
|
// Not 100% sure of how safe this is, but it's what we're using
|
||||||
// in the XPCOM ffi too
|
// in the XPCOM ffi too
|
||||||
// https://github.com/nikomatsakis/rust-memory-model/issues/2
|
// https://github.com/nikomatsakis/rust-memory-model/issues/2
|
||||||
fn zero_size_type(self, ty: &str, structs_list: &[&str]) -> Builder {
|
fn zero_size_type(self, ty: &str, structs_list: &HashSet<&str>) -> Builder {
|
||||||
if !structs_list.contains(&ty) {
|
if !structs_list.contains(ty) {
|
||||||
self.hide_type(ty)
|
self.hide_type(ty)
|
||||||
.raw_line(format!("enum {}Void {{ }}", ty))
|
.raw_line(format!("enum {}Void {{ }}", ty))
|
||||||
.raw_line(format!("pub struct {0}({0}Void);", ty))
|
.raw_line(format!("pub struct {0}({0}Void);", ty))
|
||||||
|
@ -292,318 +301,123 @@ mod bindings {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BuilderWithConfig<'a> {
|
||||||
|
builder: Builder,
|
||||||
|
config: &'a toml::Table,
|
||||||
|
used_keys: HashSet<&'static str>,
|
||||||
|
}
|
||||||
|
impl<'a> BuilderWithConfig<'a> {
|
||||||
|
fn new(builder: Builder, config: &'a toml::Table) -> Self {
|
||||||
|
BuilderWithConfig {
|
||||||
|
builder, config,
|
||||||
|
used_keys: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_list<F>(self, key: &'static str, func: F) -> BuilderWithConfig<'a>
|
||||||
|
where F: FnOnce(Builder, slice::Iter<'a, toml::Value>) -> Builder {
|
||||||
|
let mut builder = self.builder;
|
||||||
|
let config = self.config;
|
||||||
|
let mut used_keys = self.used_keys;
|
||||||
|
if let Some(list) = config.get(key) {
|
||||||
|
used_keys.insert(key);
|
||||||
|
builder = func(builder, list.as_slice().unwrap().iter());
|
||||||
|
}
|
||||||
|
BuilderWithConfig { builder, config, used_keys }
|
||||||
|
}
|
||||||
|
fn handle_items<F>(self, key: &'static str, mut func: F) -> BuilderWithConfig<'a>
|
||||||
|
where F: FnMut(Builder, &'a toml::Value) -> Builder {
|
||||||
|
self.handle_list(key, |b, iter| iter.fold(b, |b, item| func(b, item)))
|
||||||
|
}
|
||||||
|
fn handle_str_items<F>(self, key: &'static str, mut func: F) -> BuilderWithConfig<'a>
|
||||||
|
where F: FnMut(Builder, &'a str) -> Builder {
|
||||||
|
self.handle_items(key, |b, item| func(b, item.as_str().unwrap()))
|
||||||
|
}
|
||||||
|
fn handle_table_items<F>(self, key: &'static str, mut func: F) -> BuilderWithConfig<'a>
|
||||||
|
where F: FnMut(Builder, &'a toml::Table) -> Builder {
|
||||||
|
self.handle_items(key, |b, item| func(b, item.as_table().unwrap()))
|
||||||
|
}
|
||||||
|
fn handle_common(self, fixups: &mut Vec<Fixup>) -> BuilderWithConfig<'a> {
|
||||||
|
self.handle_str_items("headers", |b, item| b.header(add_include(item)))
|
||||||
|
.handle_str_items("raw-lines", |b, item| b.raw_line(item))
|
||||||
|
.handle_str_items("hide-types", |b, item| b.hide_type(item))
|
||||||
|
.handle_table_items("fixups", |builder, item| {
|
||||||
|
fixups.push(Fixup {
|
||||||
|
pat: item["pat"].as_str().unwrap().into(),
|
||||||
|
rep: item["rep"].as_str().unwrap().into(),
|
||||||
|
});
|
||||||
|
builder
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_builder(self) -> Builder {
|
||||||
|
for key in self.config.keys() {
|
||||||
|
if !self.used_keys.contains(key.as_str()) {
|
||||||
|
panic!(format!("Unknown key: {}", key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.builder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_structs(build_type: BuildType) {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Callbacks;
|
struct Callbacks(HashMap<String, RegexSet>);
|
||||||
impl ParseCallbacks for Callbacks {
|
impl ParseCallbacks for Callbacks {
|
||||||
fn enum_variant_behavior(&self,
|
fn enum_variant_behavior(&self,
|
||||||
enum_name: Option<&str>,
|
enum_name: Option<&str>,
|
||||||
variant_name: &str,
|
variant_name: &str,
|
||||||
_variant_value: EnumVariantValue)
|
_variant_value: EnumVariantValue)
|
||||||
-> Option<EnumVariantCustomBehavior> {
|
-> Option<EnumVariantCustomBehavior> {
|
||||||
if enum_name.map_or(false, |n| n == "nsCSSPropertyID") &&
|
enum_name.and_then(|enum_name| self.0.get(enum_name))
|
||||||
variant_name.starts_with("eCSSProperty_COUNT") {
|
.and_then(|regex| if regex.is_match(variant_name) {
|
||||||
Some(EnumVariantCustomBehavior::Constify)
|
Some(EnumVariantCustomBehavior::Constify)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_structs(build_type: BuildType) {
|
let builder = Builder::get_initial_builder(build_type)
|
||||||
let mut builder = Builder::get_initial_builder(build_type)
|
|
||||||
.enable_cxx_namespaces()
|
.enable_cxx_namespaces()
|
||||||
.with_codegen_config(CodegenConfig {
|
.with_codegen_config(CodegenConfig {
|
||||||
types: true,
|
types: true,
|
||||||
vars: true,
|
vars: true,
|
||||||
..CodegenConfig::nothing()
|
..CodegenConfig::nothing()
|
||||||
|
});
|
||||||
|
let mut fixups = vec![];
|
||||||
|
let builder = BuilderWithConfig::new(builder, CONFIG["structs"].as_table().unwrap())
|
||||||
|
.handle_common(&mut fixups)
|
||||||
|
.handle_str_items("bitfield-enums", |b, item| b.bitfield_enum(item))
|
||||||
|
.handle_str_items("constified-enums", |b, item| b.constified_enum(item))
|
||||||
|
.handle_str_items("whitelist-vars", |b, item| b.whitelisted_var(item))
|
||||||
|
.handle_str_items("whitelist-types", |b, item| b.whitelisted_type(item))
|
||||||
|
.handle_str_items("opaque-types", |b, item| b.opaque_type(item))
|
||||||
|
.handle_list("constified-enum-variants", |builder, iter| {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
for item in iter {
|
||||||
|
let item = item.as_table().unwrap();
|
||||||
|
let name = item["enum"].as_str().unwrap();
|
||||||
|
let variants = item["variants"].as_slice().unwrap().iter()
|
||||||
|
.map(|item| item.as_str().unwrap());
|
||||||
|
map.insert(name.into(), RegexSet::new(variants).unwrap());
|
||||||
|
}
|
||||||
|
builder.parse_callbacks(Box::new(Callbacks(map)))
|
||||||
})
|
})
|
||||||
.header(add_include("nsCSSPseudoClasses.h")) // servo/rust-bindgen#599
|
.handle_table_items("mapped-generic-types", |builder, item| {
|
||||||
.include(add_include("nsStyleStruct.h"))
|
let generic = item["generic"].as_bool().unwrap();
|
||||||
.include(add_include("mozilla/ServoPropPrefList.h"))
|
let gecko = item["gecko"].as_str().unwrap();
|
||||||
.include(add_include("mozilla/StyleAnimationValue.h"))
|
let servo = item["servo"].as_str().unwrap();
|
||||||
.include(add_include("gfxFontConstants.h"))
|
let gecko_name = gecko.rsplit("::").next().unwrap();
|
||||||
.include(add_include("nsThemeConstants.h"))
|
|
||||||
.include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h"))
|
|
||||||
.include(add_include("mozilla/AnimationPropertySegment.h"))
|
|
||||||
.include(add_include("mozilla/ComputedTiming.h"))
|
|
||||||
.include(add_include("mozilla/ComputedTimingFunction.h"))
|
|
||||||
.include(add_include("mozilla/Keyframe.h"))
|
|
||||||
.include(add_include("mozilla/ServoElementSnapshot.h"))
|
|
||||||
.include(add_include("mozilla/ServoElementSnapshotTable.h"))
|
|
||||||
.include(add_include("mozilla/dom/Element.h"))
|
|
||||||
.include(add_include("mozilla/dom/NameSpaceConstants.h"))
|
|
||||||
.include(add_include("mozilla/LookAndFeel.h"))
|
|
||||||
.include(add_include("mozilla/ServoBindings.h"))
|
|
||||||
.include(add_include("nsCSSCounterStyleRule.h"))
|
|
||||||
.include(add_include("nsCSSFontFaceRule.h"))
|
|
||||||
.include(add_include("nsMediaFeatures.h"))
|
|
||||||
.include(add_include("nsMediaList.h"))
|
|
||||||
// FIXME(emilio): Incrementally remove these "pub use"s. Probably
|
|
||||||
// mozilla::css and mozilla::dom are easier.
|
|
||||||
.raw_line("pub use self::root::*;")
|
|
||||||
.raw_line("pub use self::root::mozilla::*;")
|
|
||||||
.raw_line("pub use self::root::mozilla::css::*;")
|
|
||||||
.raw_line("pub use self::root::mozilla::dom::*;")
|
|
||||||
.raw_line("use atomic_refcell::AtomicRefCell;")
|
|
||||||
.raw_line("use data::ElementData;")
|
|
||||||
.hide_type("nsString")
|
|
||||||
.bitfield_enum("nsChangeHint")
|
|
||||||
.bitfield_enum("nsRestyleHint")
|
|
||||||
.constified_enum("UpdateAnimationsTasks")
|
|
||||||
.constified_enum("ParsingMode")
|
|
||||||
.parse_callbacks(Box::new(Callbacks));
|
|
||||||
let whitelist_vars = [
|
|
||||||
"NS_AUTHOR_SPECIFIED_.*",
|
|
||||||
"NS_THEME_.*",
|
|
||||||
"NODE_.*",
|
|
||||||
"ELEMENT_.*",
|
|
||||||
"NS_FONT_.*",
|
|
||||||
"NS_STYLE_.*",
|
|
||||||
"NS_MATHML_.*",
|
|
||||||
"NS_RADIUS_.*",
|
|
||||||
"BORDER_COLOR_.*",
|
|
||||||
"BORDER_STYLE_.*",
|
|
||||||
"mozilla::SERVO_PREF_.*",
|
|
||||||
"CSS_PSEUDO_ELEMENT_.*",
|
|
||||||
"SERVO_CSS_PSEUDO_ELEMENT_FLAGS_.*",
|
|
||||||
"kNameSpaceID_.*",
|
|
||||||
"kGenericFont_.*",
|
|
||||||
"kPresContext_.*",
|
|
||||||
];
|
|
||||||
let whitelist = [
|
|
||||||
"RawGecko.*",
|
|
||||||
"mozilla::AnimationPropertySegment",
|
|
||||||
"mozilla::ComputedTiming",
|
|
||||||
"mozilla::ComputedTimingFunction",
|
|
||||||
"mozilla::ComputedTimingFunction::BeforeFlag",
|
|
||||||
"mozilla::ServoStyleSheet",
|
|
||||||
"mozilla::ServoElementSnapshot.*",
|
|
||||||
"mozilla::CSSPseudoClassType",
|
|
||||||
"mozilla::css::SheetParsingMode",
|
|
||||||
"mozilla::css::URLMatchingFunction",
|
|
||||||
"mozilla::HalfCorner",
|
|
||||||
"mozilla::PropertyStyleAnimationValuePair",
|
|
||||||
"mozilla::TraversalRestyleBehavior",
|
|
||||||
"mozilla::TraversalRootBehavior",
|
|
||||||
"mozilla::StyleShapeRadius",
|
|
||||||
"mozilla::StyleGrid.*",
|
|
||||||
"mozilla::UpdateAnimationsTasks",
|
|
||||||
"mozilla::LookAndFeel",
|
|
||||||
".*ThreadSafe.*Holder",
|
|
||||||
"AnonymousContent",
|
|
||||||
"AudioContext",
|
|
||||||
"CapturingContentInfo",
|
|
||||||
"DefaultDelete",
|
|
||||||
"DOMIntersectionObserverEntry",
|
|
||||||
"Element",
|
|
||||||
"FontFamilyList",
|
|
||||||
"FontFamilyListRefCnt",
|
|
||||||
"FontFamilyName",
|
|
||||||
"FontFamilyType",
|
|
||||||
"FontSizePrefs",
|
|
||||||
"FragmentOrURL",
|
|
||||||
"FrameRequestCallback",
|
|
||||||
"GeckoParserExtraData",
|
|
||||||
"GeckoFontMetrics",
|
|
||||||
"gfxAlternateValue",
|
|
||||||
"gfxFontFeature",
|
|
||||||
"gfxFontVariation",
|
|
||||||
"GridNamedArea",
|
|
||||||
"HalfCorner",
|
|
||||||
"Image",
|
|
||||||
"ImageURL",
|
|
||||||
"Keyframe",
|
|
||||||
"nsAttrName",
|
|
||||||
"nsAttrValue",
|
|
||||||
"nsBorderColors",
|
|
||||||
"nscolor",
|
|
||||||
"nsChangeHint",
|
|
||||||
"nsCSSCounterStyleRule",
|
|
||||||
"nsCSSFontFaceRule",
|
|
||||||
"nsCSSKeyword",
|
|
||||||
"nsCSSPropertyID",
|
|
||||||
"nsCSSProps",
|
|
||||||
"nsCSSRect",
|
|
||||||
"nsCSSRect_heap",
|
|
||||||
"nsCSSShadowArray",
|
|
||||||
"nsCSSValue",
|
|
||||||
"nsCSSValueFloatColor",
|
|
||||||
"nsCSSValueGradient",
|
|
||||||
"nsCSSValueGradientStop",
|
|
||||||
"nsCSSValueList",
|
|
||||||
"nsCSSValueList_heap",
|
|
||||||
"nsCSSValuePair_heap",
|
|
||||||
"nsCSSValuePairList",
|
|
||||||
"nsCSSValuePairList_heap",
|
|
||||||
"nsCSSValueTokenStream",
|
|
||||||
"nsCSSValueTriplet_heap",
|
|
||||||
"nsCursorImage",
|
|
||||||
"nsFont",
|
|
||||||
"nsIAtom",
|
|
||||||
"nsMainThreadPtrHandle",
|
|
||||||
"nsMainThreadPtrHolder",
|
|
||||||
"nsMargin",
|
|
||||||
"nsMediaExpression",
|
|
||||||
"nsMediaFeature",
|
|
||||||
"nsMediaFeatures",
|
|
||||||
"nsMediaList",
|
|
||||||
"nsRect",
|
|
||||||
"nsRestyleHint",
|
|
||||||
"nsresult",
|
|
||||||
"nsSize",
|
|
||||||
"nsStyleBackground",
|
|
||||||
"nsStyleBorder",
|
|
||||||
"nsStyleColor",
|
|
||||||
"nsStyleColumn",
|
|
||||||
"nsStyleContent",
|
|
||||||
"nsStyleContentData",
|
|
||||||
"nsStyleContext",
|
|
||||||
"nsStyleCoord",
|
|
||||||
"nsStyleCounterData",
|
|
||||||
"nsStyleDisplay",
|
|
||||||
"nsStyleEffects",
|
|
||||||
"nsStyleFilter",
|
|
||||||
"nsStyleFont",
|
|
||||||
"nsStyleGradient",
|
|
||||||
"nsStyleGradientStop",
|
|
||||||
"nsStyleGridTemplate",
|
|
||||||
"nsStyleImage",
|
|
||||||
"nsStyleImageLayers",
|
|
||||||
"nsStyleList",
|
|
||||||
"nsStyleMargin",
|
|
||||||
"nsStyleOutline",
|
|
||||||
"nsStylePadding",
|
|
||||||
"nsStylePosition",
|
|
||||||
"nsStyleSVG",
|
|
||||||
"nsStyleSVGPaint",
|
|
||||||
"nsStyleSVGReset",
|
|
||||||
"nsStyleTable",
|
|
||||||
"nsStyleTableBorder",
|
|
||||||
"nsStyleText",
|
|
||||||
"nsStyleTextReset",
|
|
||||||
"nsStyleUIReset",
|
|
||||||
"nsStyleUnion",
|
|
||||||
"nsStyleUnit",
|
|
||||||
"nsStyleUserInterface",
|
|
||||||
"nsStyleVariables",
|
|
||||||
"nsStyleVisibility",
|
|
||||||
"nsStyleXUL",
|
|
||||||
"nsTArray",
|
|
||||||
"nsTArrayHeader",
|
|
||||||
"Position",
|
|
||||||
"PropertyValuePair",
|
|
||||||
"Runnable",
|
|
||||||
"ServoAttrSnapshot",
|
|
||||||
"ServoBundledURI",
|
|
||||||
"ServoElementSnapshot",
|
|
||||||
"SheetParsingMode",
|
|
||||||
"StaticRefPtr",
|
|
||||||
"StyleAnimation",
|
|
||||||
"StyleBasicShape",
|
|
||||||
"StyleBasicShapeType",
|
|
||||||
"StyleGeometryBox",
|
|
||||||
"StyleShapeSource",
|
|
||||||
"StyleTransition",
|
|
||||||
"mozilla::UniquePtr",
|
|
||||||
"mozilla::DefaultDelete",
|
|
||||||
"mozilla::Side",
|
|
||||||
"mozilla::binding_danger::AssertAndSuppressCleanupPolicy",
|
|
||||||
"mozilla::ParsingMode",
|
|
||||||
"mozilla::InheritTarget",
|
|
||||||
];
|
|
||||||
let opaque_types = [
|
|
||||||
"std::pair__PCCP",
|
|
||||||
"std::namespace::atomic___base", "std::atomic__My_base",
|
|
||||||
"std::atomic",
|
|
||||||
"std::atomic___base",
|
|
||||||
"mozilla::gfx::.*",
|
|
||||||
"FallibleTArray",
|
|
||||||
"mozilla::dom::Sequence",
|
|
||||||
"mozilla::dom::Optional",
|
|
||||||
"mozilla::dom::Nullable",
|
|
||||||
"RefPtr_Proxy",
|
|
||||||
"RefPtr_Proxy_member_function",
|
|
||||||
"nsAutoPtr_Proxy",
|
|
||||||
"nsAutoPtr_Proxy_member_function",
|
|
||||||
"mozilla::detail::PointerType",
|
|
||||||
"mozilla::Pair_Base",
|
|
||||||
"mozilla::SupportsWeakPtr",
|
|
||||||
"SupportsWeakPtr",
|
|
||||||
"mozilla::detail::WeakReference",
|
|
||||||
"mozilla::WeakPtr",
|
|
||||||
"nsWritingIterator_reference", "nsReadingIterator_reference",
|
|
||||||
"nsTObserverArray", // <- Inherits from nsAutoTObserverArray<T, 0>
|
|
||||||
"nsTHashtable", // <- Inheriting from inner typedefs that clang
|
|
||||||
// doesn't expose properly.
|
|
||||||
"nsRefPtrHashtable", "nsDataHashtable", "nsClassHashtable", // <- Ditto
|
|
||||||
"nsIDocument_SelectorCache", // <- Inherits from nsExpirationTracker<.., 4>
|
|
||||||
"nsIPresShell_ScrollAxis", // <- For some reason the alignment of this is 4
|
|
||||||
// for clang.
|
|
||||||
"nsPIDOMWindow", // <- Takes the vtable from a template parameter, and we can't
|
|
||||||
// generate it conditionally.
|
|
||||||
"JS::Rooted",
|
|
||||||
"mozilla::Maybe",
|
|
||||||
"gfxSize", // <- union { struct { T width; T height; }; T components[2] };
|
|
||||||
"gfxSize_Super", // Ditto.
|
|
||||||
"mozilla::ErrorResult", // Causes JSWhyMagic to be included & handled incorrectly.
|
|
||||||
"mozilla::StyleAnimationValue",
|
|
||||||
"StyleAnimationValue", // pulls in a whole bunch of stuff we don't need in the bindings
|
|
||||||
];
|
|
||||||
let blacklist = [
|
|
||||||
".*char_traits",
|
|
||||||
".*incompatible_char_type",
|
|
||||||
];
|
|
||||||
|
|
||||||
struct MappedGenericType {
|
|
||||||
generic: bool,
|
|
||||||
gecko: &'static str,
|
|
||||||
servo: &'static str,
|
|
||||||
}
|
|
||||||
let servo_mapped_generic_types = [
|
|
||||||
MappedGenericType {
|
|
||||||
generic: true,
|
|
||||||
gecko: "mozilla::ServoUnsafeCell",
|
|
||||||
servo: "::std::cell::UnsafeCell"
|
|
||||||
},
|
|
||||||
MappedGenericType {
|
|
||||||
generic: true,
|
|
||||||
gecko: "mozilla::ServoCell",
|
|
||||||
servo: "::std::cell::Cell"
|
|
||||||
},
|
|
||||||
MappedGenericType {
|
|
||||||
generic: false,
|
|
||||||
gecko: "ServoNodeData",
|
|
||||||
servo: "AtomicRefCell<ElementData>",
|
|
||||||
}
|
|
||||||
];
|
|
||||||
let mut fixups = vec![
|
|
||||||
Fixup {
|
|
||||||
pat: "root::nsString".into(),
|
|
||||||
rep: "::nsstring::nsStringRepr".into()
|
|
||||||
},
|
|
||||||
];
|
|
||||||
for &var in whitelist_vars.iter() {
|
|
||||||
builder = builder.whitelisted_var(var);
|
|
||||||
}
|
|
||||||
for &ty in whitelist.iter() {
|
|
||||||
builder = builder.whitelisted_type(ty);
|
|
||||||
}
|
|
||||||
for &ty in opaque_types.iter() {
|
|
||||||
builder = builder.opaque_type(ty);
|
|
||||||
}
|
|
||||||
for &ty in blacklist.iter() {
|
|
||||||
builder = builder.hide_type(ty);
|
|
||||||
}
|
|
||||||
for ty in servo_mapped_generic_types.iter() {
|
|
||||||
let gecko_name = ty.gecko.rsplit("::").next().unwrap();
|
|
||||||
builder = builder.hide_type(ty.gecko)
|
|
||||||
.raw_line(format!("pub type {0}{2} = {1}{2};", gecko_name, ty.servo,
|
|
||||||
if ty.generic { "<T>" } else { "" }));
|
|
||||||
fixups.push(Fixup {
|
fixups.push(Fixup {
|
||||||
pat: format!("root::{}", ty.gecko),
|
pat: format!("root::{}", gecko),
|
||||||
rep: format!("::gecko_bindings::structs::{}", gecko_name)
|
rep: format!("::gecko_bindings::structs::{}", gecko_name)
|
||||||
});
|
});
|
||||||
}
|
builder.hide_type(gecko)
|
||||||
|
.raw_line(format!("pub type {0}{2} = {1}{2};", gecko_name, servo,
|
||||||
|
if generic { "<T>" } else { "" }))
|
||||||
|
})
|
||||||
|
.get_builder();
|
||||||
write_binding_file(builder, structs_file(build_type), &fixups);
|
write_binding_file(builder, structs_file(build_type), &fixups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,171 +467,22 @@ mod bindings {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_bindings() {
|
fn generate_bindings() {
|
||||||
let mut builder = Builder::get_initial_builder(BuildType::Release)
|
let builder = Builder::get_initial_builder(BuildType::Release)
|
||||||
.disable_name_namespacing()
|
.disable_name_namespacing()
|
||||||
.with_codegen_config(CodegenConfig {
|
.with_codegen_config(CodegenConfig {
|
||||||
functions: true,
|
functions: true,
|
||||||
..CodegenConfig::nothing()
|
..CodegenConfig::nothing()
|
||||||
})
|
});
|
||||||
.header(add_include("mozilla/ServoBindings.h"))
|
let config = CONFIG["bindings"].as_table().unwrap();
|
||||||
.hide_type("nsACString_internal")
|
let mut structs_types = HashSet::new();
|
||||||
.hide_type("nsAString_internal")
|
let mut fixups = vec![];
|
||||||
.raw_line("pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};")
|
let mut builder = BuilderWithConfig::new(builder, config)
|
||||||
.raw_line("use gecko_bindings::structs::nsTArray;")
|
.handle_common(&mut fixups)
|
||||||
.raw_line("type nsACString_internal = nsACString;")
|
.handle_str_items("whitelist-functions", |b, item| b.whitelisted_function(item))
|
||||||
.raw_line("type nsAString_internal = nsAString;")
|
.handle_str_items("structs-types", |mut builder, ty| {
|
||||||
.whitelisted_function("Servo_.*")
|
|
||||||
.whitelisted_function("Gecko_.*");
|
|
||||||
let structs_types = [
|
|
||||||
"mozilla::css::GridTemplateAreasValue",
|
|
||||||
"mozilla::css::ImageValue",
|
|
||||||
"mozilla::css::URLValue",
|
|
||||||
"mozilla::Side",
|
|
||||||
"RawGeckoAnimationPropertySegment",
|
|
||||||
"RawGeckoComputedTiming",
|
|
||||||
"RawGeckoDocument",
|
|
||||||
"RawGeckoElement",
|
|
||||||
"RawGeckoKeyframeList",
|
|
||||||
"RawGeckoComputedKeyframeValuesList",
|
|
||||||
"RawGeckoFontFaceRuleList",
|
|
||||||
"RawGeckoNode",
|
|
||||||
"RawGeckoAnimationValueList",
|
|
||||||
"RawServoAnimationValue",
|
|
||||||
"RawServoDeclarationBlock",
|
|
||||||
"RawServoStyleRule",
|
|
||||||
"RawGeckoPresContext",
|
|
||||||
"RawGeckoPresContextOwned",
|
|
||||||
"RawGeckoStyleAnimationList",
|
|
||||||
"RawGeckoServoStyleRuleList",
|
|
||||||
"RawGeckoURLExtraData",
|
|
||||||
"RefPtr",
|
|
||||||
"CSSPseudoClassType",
|
|
||||||
"CSSPseudoElementType",
|
|
||||||
"TraversalRestyleBehavior",
|
|
||||||
"TraversalRootBehavior",
|
|
||||||
"ComputedTimingFunction_BeforeFlag",
|
|
||||||
"FontFamilyList",
|
|
||||||
"FontFamilyType",
|
|
||||||
"FontSizePrefs",
|
|
||||||
"GeckoFontMetrics",
|
|
||||||
"Keyframe",
|
|
||||||
"ServoBundledURI",
|
|
||||||
"ServoElementSnapshot",
|
|
||||||
"ServoElementSnapshotTable",
|
|
||||||
"SheetParsingMode",
|
|
||||||
"StyleBasicShape",
|
|
||||||
"StyleBasicShapeType",
|
|
||||||
"StyleShapeSource",
|
|
||||||
"StyleTransition",
|
|
||||||
"nsCSSCounterStyleRule",
|
|
||||||
"nsCSSFontFaceRule",
|
|
||||||
"nsCSSKeyword",
|
|
||||||
"nsCSSPropertyID",
|
|
||||||
"nsCSSShadowArray",
|
|
||||||
"nsCSSUnit",
|
|
||||||
"nsCSSValue",
|
|
||||||
"nsCSSValueSharedList",
|
|
||||||
"nsChangeHint",
|
|
||||||
"nsCursorImage",
|
|
||||||
"nsFont",
|
|
||||||
"nsIAtom",
|
|
||||||
"nsCompatibility",
|
|
||||||
"nsMediaFeature",
|
|
||||||
"nsRestyleHint",
|
|
||||||
"nsStyleBackground",
|
|
||||||
"nsStyleBorder",
|
|
||||||
"nsStyleColor",
|
|
||||||
"nsStyleColumn",
|
|
||||||
"nsStyleContent",
|
|
||||||
"nsStyleContentData",
|
|
||||||
"nsStyleContentType",
|
|
||||||
"nsStyleContext",
|
|
||||||
"nsStyleCoord",
|
|
||||||
"nsStyleCoord_Calc",
|
|
||||||
"nsStyleCoord_CalcValue",
|
|
||||||
"nsStyleDisplay",
|
|
||||||
"nsStyleEffects",
|
|
||||||
"nsStyleFilter",
|
|
||||||
"nsStyleFont",
|
|
||||||
"nsStyleGradient",
|
|
||||||
"nsStyleGradientStop",
|
|
||||||
"nsStyleGridTemplate",
|
|
||||||
"nsStyleImage",
|
|
||||||
"nsStyleImageLayers",
|
|
||||||
"nsStyleImageLayers_Layer",
|
|
||||||
"nsStyleImageLayers_LayerType",
|
|
||||||
"nsStyleImageRequest",
|
|
||||||
"nsStyleList",
|
|
||||||
"nsStyleMargin",
|
|
||||||
"nsStyleOutline",
|
|
||||||
"nsStylePadding",
|
|
||||||
"nsStylePosition",
|
|
||||||
"nsStyleQuoteValues",
|
|
||||||
"nsStyleSVG",
|
|
||||||
"nsStyleSVGPaint",
|
|
||||||
"nsStyleSVGReset",
|
|
||||||
"nsStyleTable",
|
|
||||||
"nsStyleTableBorder",
|
|
||||||
"nsStyleText",
|
|
||||||
"nsStyleTextReset",
|
|
||||||
"nsStyleUIReset",
|
|
||||||
"nsStyleUnion",
|
|
||||||
"nsStyleUnit",
|
|
||||||
"nsStyleUserInterface",
|
|
||||||
"nsStyleVariables",
|
|
||||||
"nsStyleVisibility",
|
|
||||||
"nsStyleXUL",
|
|
||||||
"nsTimingFunction",
|
|
||||||
"nscolor",
|
|
||||||
"nscoord",
|
|
||||||
"nsresult",
|
|
||||||
"Loader",
|
|
||||||
"ServoStyleSheet",
|
|
||||||
"EffectCompositor_CascadeLevel",
|
|
||||||
"UpdateAnimationsTasks",
|
|
||||||
"ParsingMode",
|
|
||||||
"InheritTarget",
|
|
||||||
"URLMatchingFunction",
|
|
||||||
];
|
|
||||||
struct ArrayType {
|
|
||||||
cpp_type: &'static str,
|
|
||||||
rust_type: &'static str
|
|
||||||
}
|
|
||||||
let array_types = [
|
|
||||||
ArrayType { cpp_type: "uintptr_t", rust_type: "usize" },
|
|
||||||
];
|
|
||||||
struct ServoOwnedType {
|
|
||||||
name: &'static str,
|
|
||||||
opaque: bool,
|
|
||||||
}
|
|
||||||
let servo_owned_types = [
|
|
||||||
ServoOwnedType { name: "RawServoStyleSet", opaque: true },
|
|
||||||
ServoOwnedType { name: "StyleChildrenIterator", opaque: true },
|
|
||||||
ServoOwnedType { name: "ServoElementSnapshot", opaque: false },
|
|
||||||
ServoOwnedType { name: "RawServoAnimationValueMap", opaque: true },
|
|
||||||
];
|
|
||||||
let servo_immutable_borrow_types = [
|
|
||||||
"RawGeckoNode",
|
|
||||||
"RawGeckoElement",
|
|
||||||
"RawGeckoDocument",
|
|
||||||
"RawServoDeclarationBlockStrong",
|
|
||||||
"RawGeckoPresContext",
|
|
||||||
"RawGeckoStyleAnimationList",
|
|
||||||
];
|
|
||||||
let servo_borrow_types = [
|
|
||||||
"nsCSSValue",
|
|
||||||
"nsTimingFunction",
|
|
||||||
"RawGeckoAnimationPropertySegment",
|
|
||||||
"RawGeckoAnimationValueList",
|
|
||||||
"RawGeckoComputedTiming",
|
|
||||||
"RawGeckoKeyframeList",
|
|
||||||
"RawGeckoComputedKeyframeValuesList",
|
|
||||||
"RawGeckoFontFaceRuleList",
|
|
||||||
"RawGeckoServoStyleRuleList",
|
|
||||||
];
|
|
||||||
for &ty in structs_types.iter() {
|
|
||||||
builder = builder.hide_type(ty)
|
builder = builder.hide_type(ty)
|
||||||
.raw_line(format!("use gecko_bindings::structs::{};", ty));
|
.raw_line(format!("use gecko_bindings::structs::{};", ty));
|
||||||
|
structs_types.insert(ty);
|
||||||
// TODO this is hacky, figure out a better way to do it without
|
// TODO this is hacky, figure out a better way to do it without
|
||||||
// hardcoding everything...
|
// hardcoding everything...
|
||||||
if ty.starts_with("nsStyle") {
|
if ty.starts_with("nsStyle") {
|
||||||
|
@ -825,12 +490,39 @@ mod bindings {
|
||||||
.raw_line(format!("unsafe impl Send for {} {{}}", ty))
|
.raw_line(format!("unsafe impl Send for {} {{}}", ty))
|
||||||
.raw_line(format!("unsafe impl Sync for {} {{}}", ty));
|
.raw_line(format!("unsafe impl Sync for {} {{}}", ty));
|
||||||
}
|
}
|
||||||
}
|
builder
|
||||||
for &ArrayType { cpp_type, rust_type } in array_types.iter() {
|
})
|
||||||
builder = builder.hide_type(format!("nsTArrayBorrowed_{}", cpp_type))
|
// TODO This was added due to servo/rust-bindgen#75, but
|
||||||
.raw_line(format!("pub type nsTArrayBorrowed_{}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{}>;",
|
// that has been fixed in clang 4.0+. When we switch people
|
||||||
|
// to libclang 4.0, we can remove this.
|
||||||
|
.handle_table_items("array-types", |builder, item| {
|
||||||
|
let cpp_type = item["cpp-type"].as_str().unwrap();
|
||||||
|
let rust_type = item["rust-type"].as_str().unwrap();
|
||||||
|
builder.hide_type(format!("nsTArrayBorrowed_{}", cpp_type))
|
||||||
|
.raw_line(format!(concat!("pub type nsTArrayBorrowed_{}<'a> = ",
|
||||||
|
"&'a mut ::gecko_bindings::structs::nsTArray<{}>;"),
|
||||||
cpp_type, rust_type))
|
cpp_type, rust_type))
|
||||||
|
})
|
||||||
|
.handle_table_items("servo-owned-types", |mut builder, item| {
|
||||||
|
let name = item["name"].as_str().unwrap();
|
||||||
|
builder = builder.hide_type(format!("{}Owned", name))
|
||||||
|
.raw_line(format!("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;", name))
|
||||||
|
.hide_type(format!("{}OwnedOrNull", name))
|
||||||
|
.raw_line(format!(concat!("pub type {0}OwnedOrNull = ",
|
||||||
|
"::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;"), name))
|
||||||
|
.mutable_borrowed_type(name);
|
||||||
|
if item["opaque"].as_bool().unwrap() {
|
||||||
|
builder = builder.zero_size_type(name, &structs_types);
|
||||||
}
|
}
|
||||||
|
builder
|
||||||
|
})
|
||||||
|
.handle_str_items("servo-immutable-borrow-types", |b, ty| b.borrowed_type(ty))
|
||||||
|
// Right now the only immutable borrow types are ones which we import
|
||||||
|
// from the |structs| module. As such, we don't need to create an opaque
|
||||||
|
// type with zero_size_type. If we ever introduce immutable borrow types
|
||||||
|
// which _do_ need to be opaque, we'll need a separate mode.
|
||||||
|
.handle_str_items("servo-borrow-types", |b, ty| b.mutable_borrowed_type(ty))
|
||||||
|
.get_builder();
|
||||||
for ty in get_arc_types().iter() {
|
for ty in get_arc_types().iter() {
|
||||||
builder = builder
|
builder = builder
|
||||||
.hide_type(format!("{}Strong", ty))
|
.hide_type(format!("{}Strong", ty))
|
||||||
|
@ -838,34 +530,6 @@ mod bindings {
|
||||||
.borrowed_type(ty)
|
.borrowed_type(ty)
|
||||||
.zero_size_type(ty, &structs_types);
|
.zero_size_type(ty, &structs_types);
|
||||||
}
|
}
|
||||||
for &ServoOwnedType { name, opaque } in servo_owned_types.iter() {
|
|
||||||
builder = builder
|
|
||||||
.hide_type(format!("{}Owned", name))
|
|
||||||
.raw_line(format!("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;", name))
|
|
||||||
.hide_type(format!("{}OwnedOrNull", name))
|
|
||||||
.raw_line(format!("pub type {0}OwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;",
|
|
||||||
name))
|
|
||||||
.mutable_borrowed_type(name);
|
|
||||||
if opaque {
|
|
||||||
builder = builder.zero_size_type(name, &structs_types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for &ty in servo_immutable_borrow_types.iter() {
|
|
||||||
builder = builder.borrowed_type(ty);
|
|
||||||
}
|
|
||||||
for &ty in servo_borrow_types.iter() {
|
|
||||||
builder = builder.mutable_borrowed_type(ty);
|
|
||||||
// Right now the only immutable borrow types are ones which we import
|
|
||||||
// from the |structs| module. As such, we don't need to create an opaque
|
|
||||||
// type with zero_size_type. If we ever introduce immutable borrow types
|
|
||||||
// which _do_ need to be opaque, we'll need a separate mode.
|
|
||||||
}
|
|
||||||
let fixups = vec![
|
|
||||||
Fixup { // hack for gecko-owned string
|
|
||||||
pat: "<nsString".into(),
|
|
||||||
rep: "<nsStringRepr".into()
|
|
||||||
},
|
|
||||||
];
|
|
||||||
write_binding_file(builder, BINDINGS_FILE, &fixups);
|
write_binding_file(builder, BINDINGS_FILE, &fixups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue