diff --git a/Cargo.lock b/Cargo.lock index fbf547ae545..786570b6872 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,14 @@ name = "ascii" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ascii-canvas" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atomic_refcell" version = "0.1.0" @@ -237,6 +245,19 @@ dependencies = [ "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bit-set" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-vec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.0.3" @@ -1010,6 +1031,11 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "diff" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "digest" version = "0.7.6" @@ -1043,6 +1069,18 @@ dependencies = [ "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "docopt" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dom_struct" version = "0.0.1" @@ -1113,6 +1151,14 @@ dependencies = [ "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", ] +[[package]] +name = "ena" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "encoding_rs" version = "0.8.12" @@ -2190,6 +2236,35 @@ name = "khronos_api" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lalrpop" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lalrpop-util 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lalrpop-util" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "layout" version = "0.0.1" @@ -3592,6 +3667,9 @@ dependencies = [ [[package]] name = "script_plugins" version = "0.0.1" +dependencies = [ + "webidl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "script_plugins_tests" @@ -4217,6 +4295,11 @@ name = "strsim" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "style" version = "0.0.1" @@ -4389,6 +4472,15 @@ dependencies = [ "utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "1.0.4" @@ -4944,6 +5036,15 @@ dependencies = [ "webdriver 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "webidl" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lalrpop 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lalrpop-util 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "webrender" version = "0.60.0" @@ -5253,6 +5354,7 @@ dependencies = [ "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2" "checksum ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50" +"checksum ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b385d69402821a1c254533a011a312531cbcc0e3e24f19bbb4747a5a2daf37e2" "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum azure 0.35.0 (git+https://github.com/servo/rust-azure)" = "" @@ -5263,6 +5365,8 @@ dependencies = [ "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff" "checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0" "checksum bindgen 0.49.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33e1b67a27bca31fd12a683b2a3618e275311117f48cfcc892e18403ff889026" +"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" +"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" @@ -5326,15 +5430,18 @@ dependencies = [ "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86" "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871" "checksum device 0.0.1 (git+https://github.com/servo/devices)" = "" +"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37a76dd8b997af7107d0bb69d43903cf37153a18266f8b3fdb9911f28efb5444" "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" +"checksum docopt 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db2906c2579b5b7207fc1e328796a9a8835dc44e22dbe8e460b1d636f9a7b225" "checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8" "checksum dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c31c624339dab99c223a4b26c2e803b7c248adaca91549ce654c76f39a03f5c8" "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" +"checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00" "checksum encoding_rs 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ca20350a7cb5aab5b9034731123d6d412caf3e92d4985e739e411ba0955fd0eb" "checksum energy-monitor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe872d0664f1cc60db36349af245d892ee67d3c8f78055df0ebc43271fd4e05c" "checksum energymon 0.3.0 (git+https://github.com/energymon/energymon-rust.git)" = "" @@ -5432,6 +5539,8 @@ dependencies = [ "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum keyboard-types 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53b536dc22c0dabb295e85dbd0c062023885b12b8db24e1d86833f4e50ea7959" "checksum khronos_api 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62237e6d326bd5871cd21469323bf096de81f1618cd82cbaf5d87825335aeb49" +"checksum lalrpop 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2e80bee40b22bca46665b4ef1f3cd88ed0fb043c971407eac17a0712c02572" +"checksum lalrpop-util 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)" = "33b27d8490dbe1f9704b0088d61e8d46edc10d5673a8829836c6ded26a9912c7" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50" "checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73" @@ -5576,11 +5685,13 @@ dependencies = [ "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb" "checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b" "checksum tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b" +"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" @@ -5638,6 +5749,7 @@ dependencies = [ "checksum wayland-scanner 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f1927ee62e4e149c010dc9eca8ca47e238416cd6f45f688eb9f8a8e9c3794c30" "checksum wayland-sys 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ca41ed78a12256f81df6f53fcbe4503213ba442e02cdad3c9c888a64a668eaf4" "checksum webdriver 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0533b0b0a05e2e5c081317759a038482806c6085c9605dded03c8bbd2498b042" +"checksum webidl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f807f7488d680893f7188aa09d7672a3a0a8461975a098a2edf0a52e3fee29" "checksum webrender 0.60.0 (git+https://github.com/servo/webrender)" = "" "checksum webrender_api 0.60.0 (git+https://github.com/servo/webrender)" = "" "checksum webrender_build 0.0.1 (git+https://github.com/servo/webrender)" = "" diff --git a/components/script_plugins/Cargo.toml b/components/script_plugins/Cargo.toml index 235303d2983..1999b3e8e82 100644 --- a/components/script_plugins/Cargo.toml +++ b/components/script_plugins/Cargo.toml @@ -12,3 +12,6 @@ plugin = true [features] unrooted_must_root_lint = [] webidl_lint = [] + +[dependencies] +webidl = "0.8" diff --git a/components/script_plugins/lib.rs b/components/script_plugins/lib.rs index eda133d4b7b..7d0460bf5a1 100644 --- a/components/script_plugins/lib.rs +++ b/components/script_plugins/lib.rs @@ -25,6 +25,8 @@ extern crate rustc; extern crate rustc_plugin; extern crate syntax; +extern crate webidl; + use rustc_plugin::Registry; use syntax::feature_gate::AttributeType::Whitelisted; diff --git a/components/script_plugins/webidl_must_inherit.rs b/components/script_plugins/webidl_must_inherit.rs index 96ef9e75db2..74256ce75aa 100644 --- a/components/script_plugins/webidl_must_inherit.rs +++ b/components/script_plugins/webidl_must_inherit.rs @@ -5,11 +5,18 @@ use rustc::hir::{self, HirId}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass}; use rustc::ty; +use std::boxed; use std::env; - +use std::error::Error; +use std::fmt; +use std::fs; use std::io; use std::path; use syntax::ast; +use webidl::ast::*; +use webidl::visitor::*; +use webidl::*; + declare_lint!( WEBIDL_INHERIT_CORRECT, Deny, @@ -18,17 +25,52 @@ declare_lint!( pub struct WebIdlPass; +#[derive(Clone, Debug)] +pub enum WebIdlError { + ParentMismatch { + name: String, + rust_parent: String, + webidl_parent: String, + }, +} + +impl fmt::Display for WebIdlError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + WebIdlError::ParentMismatch { + name, + rust_parent, + webidl_parent, + } => { + return write!(f, "webidl-rust inheritance mismatch, rust: {:?}, rust parent: {:?}, webidl parent: {:?}", + &name, &rust_parent, &webidl_parent); + }, + } + } +} + +impl Error for WebIdlError { + fn description(&self) -> &str { + "WebIdlError" + } + + fn cause(&self) -> Option<&Error> { + None + } +} + impl WebIdlPass { pub fn new() -> WebIdlPass { WebIdlPass } } -fn get_typ_name(typ: String) -> Option { +fn get_typ_name(typ: String) -> String { if let Some(i) = typ.rfind(':') { - return Some(typ[i + 1..].to_string()); + typ[i + 1..].to_string() + } else { + typ } - None } fn get_webidl_path(struct_name: &str) -> io::Result { @@ -39,7 +81,6 @@ fn get_webidl_path(struct_name: &str) -> io::Result { return Ok(dir); } -/// Checks if a type is unrooted or contains any owned unrooted types fn is_webidl_ty(cx: &LateContext, ty: &ty::TyS) -> bool { let mut ret = false; ty.maybe_walk(|t| { @@ -59,13 +100,31 @@ fn is_webidl_ty(cx: &LateContext, ty: &ty::TyS) -> bool { ret } -fn check_webidl(name: &str, parent_name: Option) -> io::Result<()> { +fn check_inherits(code: &str, name: &str, parent_name: &str) -> Result<(), Box> { + let idl = parse_string(code)?; + let mut visitor = InterfaceVisitor::new(name.to_string()); + visitor.visit(&idl); + let inherits = visitor.get_inherits(); + + println!("inherits: {:?}, parent_name: {:?}", inherits, parent_name); + + if inherits == parent_name { + return Ok(()); + } + Err(boxed::Box::from(WebIdlError::ParentMismatch { + name: name.to_string(), + rust_parent: parent_name.to_string(), + webidl_parent: inherits.to_string(), + })) +} + +fn check_webidl(name: &str, parent_name: Option) -> Result<(), Box> { let path = get_webidl_path(&name)?; println!("struct_webidl_path: {:?}", &path); if let Some(parent) = parent_name { - let parent_path = get_webidl_path(&parent)?; - println!("parent_path: {:?}", &parent_path); + let code = fs::read_to_string(path)?; + return check_inherits(&code, &name, &parent); } Ok(()) @@ -110,24 +169,55 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WebIdlPass { for ref field in def.fields() { let def_id = cx.tcx.hir().local_def_id_from_hir_id(field.hir_id); let ty = cx.tcx.type_of(def_id); - let typ = ty.to_string(); - if let Some(typ_name) = get_typ_name(ty.to_string()) { - parent_typ_name = Some(typ_name); - break; - } else { - cx.span_lint(WEBIDL_INHERIT_CORRECT, field.span, "Cannot get type name"); - } + let typ_name = get_typ_name(ty.to_string()); + parent_typ_name = Some(typ_name); // Only first field is relevant. break; } - // TODO Open and parse corresponding webidl file. - cx.span_lint(WEBIDL_INHERIT_CORRECT, item.ident.span, "WEBIDL present."); - match check_webidl(&struct_name, parent_typ_name) { Ok(()) => {}, - Err(e) => println!("ERRORRR: {:?}", e), + Err(e) => { + let description = format!("{}", e); + cx.span_lint(WEBIDL_INHERIT_CORRECT, item.ident.span, &description) + }, }; } } + +struct InterfaceVisitor { + name: String, + inherits: String, +} + +impl InterfaceVisitor { + pub fn new(name: String) -> Self { + InterfaceVisitor { + name: name, + inherits: String::new(), + } + } + + pub fn get_inherits(&self) -> &String { + &self.inherits + } +} + +impl<'ast> ImmutableVisitor<'ast> for InterfaceVisitor { + fn visit_callback_interface(&mut self, callback_interface: &'ast CallbackInterface) { + if callback_interface.name == self.name { + if let Some(ref inherit) = callback_interface.inherits { + self.inherits = inherit.to_string() + } + } + } + + fn visit_non_partial_interface(&mut self, non_partial_interface: &'ast NonPartialInterface) { + if non_partial_interface.name == self.name { + if let Some(ref inherit) = non_partial_interface.inherits { + self.inherits = inherit.to_string() + } + } + } +}