diff options
-rw-r--r-- | Cargo.lock | 10 | ||||
-rw-r--r-- | components/deny_public_fields/Cargo.toml | 14 | ||||
-rw-r--r-- | components/deny_public_fields/lib.rs | 26 | ||||
-rw-r--r-- | components/plugins/jstraceable.rs | 1 | ||||
-rw-r--r-- | components/plugins/lib.rs | 7 | ||||
-rw-r--r-- | components/plugins/lints/mod.rs | 2 | ||||
-rw-r--r-- | components/plugins/lints/privatize.rs | 41 | ||||
-rw-r--r-- | components/plugins/lints/transmute_type.rs | 45 | ||||
-rw-r--r-- | components/script/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/iterable.rs | 32 | ||||
-rw-r--r-- | components/script/dom/eventtarget.rs | 3 | ||||
-rw-r--r-- | components/script/dom/range.rs | 4 | ||||
-rw-r--r-- | components/script/lib.rs | 2 | ||||
-rw-r--r-- | components/script/timers.rs | 9 | ||||
-rw-r--r-- | tests/compiletest/plugin/Cargo.toml | 1 | ||||
-rw-r--r-- | tests/compiletest/plugin/compile-fail/privatize.rs | 9 | ||||
-rw-r--r-- | tests/compiletest/plugin/compile-fail/transmute_type.rs | 19 | ||||
-rw-r--r-- | tests/compiletest/plugin/lib.rs | 2 |
18 files changed, 71 insertions, 157 deletions
diff --git a/Cargo.lock b/Cargo.lock index b99056eac73..37d905f21c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -598,6 +598,14 @@ dependencies = [ ] [[package]] +name = "deny_public_fields" +version = "0.0.1" +dependencies = [ + "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "deque" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2030,6 +2038,7 @@ name = "plugin_compiletest" version = "0.0.1" dependencies = [ "compiletest_helper 0.0.1", + "deny_public_fields 0.0.1", "plugins 0.0.1", "script 0.0.1", ] @@ -2256,6 +2265,7 @@ dependencies = [ "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "domobject_derive 0.0.1", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/deny_public_fields/Cargo.toml b/components/deny_public_fields/Cargo.toml new file mode 100644 index 00000000000..de5c99c0495 --- /dev/null +++ b/components/deny_public_fields/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "deny_public_fields" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +publish = false + +[lib] +path = "lib.rs" +proc-macro = true + +[dependencies] +syn = "0.10" +synstructure = "0.4" diff --git a/components/deny_public_fields/lib.rs b/components/deny_public_fields/lib.rs new file mode 100644 index 00000000000..a43db51e4af --- /dev/null +++ b/components/deny_public_fields/lib.rs @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate proc_macro; +extern crate syn; +extern crate synstructure; + +#[proc_macro_derive(DenyPublicFields)] +pub fn expand_token_stream(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + expand_string(&input.to_string()).parse().unwrap() +} + +fn expand_string(input: &str) -> String { + let type_ = syn::parse_macro_input(input).unwrap(); + + let style = synstructure::BindStyle::Ref.into(); + synstructure::each_field(&type_, &style, |binding| { + if binding.field.vis != syn::Visibility::Inherited { + panic!("Field {} should not be public", binding.ident); + } + "".to_owned() + }); + + "".to_owned() +} diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index 498f4006010..9bc9ead6299 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -11,7 +11,6 @@ pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotat if let Annotatable::Item(item) = anno { let mut item2 = (*item).clone(); item2.attrs.push(quote_attr!(cx, #[must_root])); - item2.attrs.push(quote_attr!(cx, #[privatize])); item2.attrs.push(quote_attr!(cx, #[repr(C)])); item2.attrs.push(quote_attr!(cx, #[derive(JSTraceable)])); item2.attrs.push(quote_attr!(cx, #[derive(HeapSizeOf)])); diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index eca3feef5f1..7b897cb10e0 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -6,11 +6,11 @@ //! //! Attributes this crate provides: //! -//! - `#[privatize]` : Forces all fields in a struct/enum to be private +//! - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private //! - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate //! - `#[must_root]` : Prevents data of the marked type from being used on the stack. //! See the lints module for more details -//! - `#[dom_struct]` : Implies `#[privatize]`,`#[derive(JSTraceable)]`, and `#[must_root]`. +//! - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`. //! Use this for structs that correspond to a DOM type @@ -44,14 +44,11 @@ pub fn plugin_registrar(reg: &mut Registry) { MultiModifier(box jstraceable::expand_dom_struct)); reg.register_late_lint_pass(box lints::unrooted_must_root::UnrootedPass::new()); - reg.register_late_lint_pass(box lints::privatize::PrivatizePass); reg.register_late_lint_pass(box lints::inheritance_integrity::InheritancePass); - reg.register_late_lint_pass(box lints::transmute_type::TransmutePass); reg.register_early_lint_pass(box lints::ban::BanPass); reg.register_attribute("_dom_struct_marker".to_string(), Whitelisted); reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted); reg.register_attribute("must_root".to_string(), Whitelisted); - reg.register_attribute("privatize".to_string(), Whitelisted); reg.register_attribute("servo_lang".to_string(), Whitelisted); register_clippy(reg); } diff --git a/components/plugins/lints/mod.rs b/components/plugins/lints/mod.rs index 31c6b90737b..5b1debed0a2 100644 --- a/components/plugins/lints/mod.rs +++ b/components/plugins/lints/mod.rs @@ -4,6 +4,4 @@ pub mod ban; pub mod inheritance_integrity; -pub mod privatize; -pub mod transmute_type; pub mod unrooted_must_root; diff --git a/components/plugins/lints/privatize.rs b/components/plugins/lints/privatize.rs deleted file mode 100644 index e6a44015d81..00000000000 --- a/components/plugins/lints/privatize.rs +++ /dev/null @@ -1,41 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use rustc::hir; -use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use syntax::ast; - -declare_lint!(PRIVATIZE, Deny, - "Allows to enforce private fields for struct definitions"); - -/// Lint for keeping DOM fields private -/// -/// This lint (disable with `-A privatize`/`#[allow(privatize)]`) ensures all types marked with `#[privatize]` -/// have no public fields -pub struct PrivatizePass; - -impl LintPass for PrivatizePass { - fn get_lints(&self) -> LintArray { - lint_array!(PRIVATIZE) - } -} - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PrivatizePass { - fn check_struct_def(&mut self, - cx: &LateContext, - def: &hir::VariantData, - _n: ast::Name, - _gen: &hir::Generics, - id: ast::NodeId) { - if cx.tcx.has_attr(cx.tcx.hir.local_def_id(id), "privatize") { - for field in def.fields() { - if field.vis == hir::Public { - cx.span_lint(PRIVATIZE, field.span, - &format!("Field {} is public where only private fields are allowed", - field.name)); - } - } - } - } -} diff --git a/components/plugins/lints/transmute_type.rs b/components/plugins/lints/transmute_type.rs deleted file mode 100644 index 15e760291f9..00000000000 --- a/components/plugins/lints/transmute_type.rs +++ /dev/null @@ -1,45 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use rustc::hir; -use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; - -declare_lint!(TRANSMUTE_TYPE_LINT, Allow, - "Warn and report types being transmuted"); - -/// Lint for auditing transmutes -/// -/// This lint (off by default, enable with `-W transmute-type-lint`) warns about all the transmutes -/// being used, along with the types they transmute to/from. -pub struct TransmutePass; - -impl LintPass for TransmutePass { - fn get_lints(&self) -> LintArray { - lint_array!(TRANSMUTE_TYPE_LINT) - } -} - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutePass { - fn check_expr(&mut self, cx: &LateContext, ex: &hir::Expr) { - match ex.node { - hir::ExprCall(ref expr, ref args) => { - match expr.node { - hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { - if path.segments.last() - .map_or(false, |ref segment| &*segment.name.as_str() == "transmute") && - args.len() == 1 { - cx.span_lint(TRANSMUTE_TYPE_LINT, ex.span, - &format!("Transmute to {:?} from {:?} detected", - cx.tables.expr_ty(ex), - cx.tables.expr_ty(&args.get(0).unwrap()) - )); - } - } - _ => {} - } - } - _ => {} - } - } -} diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index a800dffac74..84ead24b21f 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -35,6 +35,7 @@ canvas_traits = {path = "../canvas_traits"} caseless = "0.1.0" cookie = {version = "0.2.5", features = ["serialize-rustc"]} cssparser = {version = "0.8", features = ["heap_size", "serde-serialization"]} +deny_public_fields = {path = "../deny_public_fields"} devtools_traits = {path = "../devtools_traits"} domobject_derive = {path = "../domobject_derive"} encoding = "0.2" diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 35e83880b4f..08439d16517 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -11,11 +11,11 @@ use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyAndVal use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyOrValueResult; use dom::bindings::error::Fallible; use dom::bindings::js::{JS, Root}; -use dom::bindings::reflector::{Reflector, DomObject, MutDomObject, reflect_dom_object}; +use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::trace::JSTraceable; use dom::globalscope::GlobalScope; use js::conversions::ToJSValConvertible; -use js::jsapi::{JSContext, JSObject, MutableHandleValue, MutableHandleObject, HandleValue}; +use js::jsapi::{HandleValue, JSContext, JSObject, MutableHandleObject}; use js::jsval::UndefinedValue; use std::cell::Cell; use std::ptr; @@ -47,11 +47,7 @@ pub trait Iterable { /// An iterator over the iterable entries of a given DOM interface. //FIXME: #12811 prevents dom_struct with type parameters -//#[dom_struct] -#[must_root] -#[privatize] -#[derive(JSTraceable)] -#[derive(HeapSizeOf)] +#[dom_struct] pub struct IterableIterator<T: DomObject + JSTraceable + Iterable> { reflector: Reflector, iterable: JS<T>, @@ -59,28 +55,6 @@ pub struct IterableIterator<T: DomObject + JSTraceable + Iterable> { index: Cell<u32>, } -impl<T: DomObject + JSTraceable + Iterable> DomObject for IterableIterator<T> { - fn reflector<'a>(&'a self) -> &'a Reflector { - &self.reflector - } -} - -impl<T: DomObject + JSTraceable + Iterable> MutDomObject for IterableIterator<T> { - fn init_reflector(&mut self, obj: *mut JSObject) { - self.reflector.set_jsobject(obj); - } -} - -impl<T: DomObject + JSTraceable + Iterable> ToJSValConvertible for IterableIterator<T> { - #[allow(unsafe_code)] - unsafe fn to_jsval(&self, - cx: *mut JSContext, - rval: MutableHandleValue) { - let object = DomObject::reflector(self).get_jsobject(); - object.to_jsval(cx, rval) - } -} - impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> { /// Create a new iterator instance for the provided iterable DOM interface. pub fn new(iterable: &T, diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 1e1a52830a6..57eedd8e333 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -220,8 +220,7 @@ impl CompiledEventListener { } } -#[derive(JSTraceable, Clone, PartialEq, HeapSizeOf)] -#[privatize] +#[derive(Clone, DenyPublicFields, HeapSizeOf, JSTraceable, PartialEq)] /// A listener in a collection of event listeners. struct EventListenerEntry { phase: ListenerPhase, diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index e9e3a484d41..65b4d1b8487 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -929,10 +929,8 @@ impl RangeMethods for Range { } } -#[derive(JSTraceable)] +#[derive(DenyPublicFields, HeapSizeOf, JSTraceable)] #[must_root] -#[privatize] -#[derive(HeapSizeOf)] pub struct BoundaryPoint { node: MutJS<Node>, offset: Cell<u32>, diff --git a/components/script/lib.rs b/components/script/lib.rs index 3242e0ccf01..c7a1598c889 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -38,6 +38,8 @@ extern crate cookie as cookie_rs; extern crate core; #[macro_use] extern crate cssparser; +#[macro_use] +extern crate deny_public_fields; extern crate devtools_traits; #[macro_use] extern crate domobject_derive; diff --git a/components/script/timers.rs b/components/script/timers.rs index c1f0a1de6c4..5de0dc2416b 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -28,8 +28,7 @@ use std::rc::Rc; #[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord, Debug)] pub struct OneshotTimerHandle(i32); -#[derive(JSTraceable, HeapSizeOf)] -#[privatize] +#[derive(DenyPublicFields, HeapSizeOf, JSTraceable)] pub struct OneshotTimers { js_timers: JsTimers, #[ignore_heap_size_of = "Defined in std"] @@ -53,8 +52,7 @@ pub struct OneshotTimers { expected_event_id: Cell<TimerEventId>, } -#[derive(JSTraceable, HeapSizeOf)] -#[privatize] +#[derive(DenyPublicFields, HeapSizeOf, JSTraceable)] struct OneshotTimer { handle: OneshotTimerHandle, source: TimerSource, @@ -302,8 +300,7 @@ impl OneshotTimers { #[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord)] pub struct JsTimerHandle(i32); -#[derive(JSTraceable, HeapSizeOf)] -#[privatize] +#[derive(DenyPublicFields, HeapSizeOf, JSTraceable)] pub struct JsTimers { next_timer_handle: Cell<JsTimerHandle>, active_timers: DOMRefCell<HashMap<JsTimerHandle, JsTimerEntry>>, diff --git a/tests/compiletest/plugin/Cargo.toml b/tests/compiletest/plugin/Cargo.toml index 453905b9d4f..86d715a8186 100644 --- a/tests/compiletest/plugin/Cargo.toml +++ b/tests/compiletest/plugin/Cargo.toml @@ -11,5 +11,6 @@ doctest = false [dependencies] compiletest_helper = {path = "../helper"} +deny_public_fields = {path = "../../../components/deny_public_fields"} plugins = {path = "../../../components/plugins"} script = {path = "../../../components/script"} diff --git a/tests/compiletest/plugin/compile-fail/privatize.rs b/tests/compiletest/plugin/compile-fail/privatize.rs index a6f2ffdbe62..ef185c2169c 100644 --- a/tests/compiletest/plugin/compile-fail/privatize.rs +++ b/tests/compiletest/plugin/compile-fail/privatize.rs @@ -2,14 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#![feature(plugin, custom_attribute)] -#![plugin(plugins)] #![allow(dead_code)] -#[privatize] +#[macro_use] +extern crate deny_public_fields; + +#[derive(DenyPublicFields)] +//~^ ERROR custom derive attribute panicked struct Foo { pub v1: i32, - //~^ ERROR Field v1 is public where only private fields are allowed v2: i32 } diff --git a/tests/compiletest/plugin/compile-fail/transmute_type.rs b/tests/compiletest/plugin/compile-fail/transmute_type.rs deleted file mode 100644 index 42bdd8c8c0f..00000000000 --- a/tests/compiletest/plugin/compile-fail/transmute_type.rs +++ /dev/null @@ -1,19 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#![feature(plugin)] -#![plugin(plugins)] -#![allow(dead_code)] -#![deny(transmute_type_lint)] - -use std::mem::{self, transmute}; - - -fn main() { - let _: &[u8] = unsafe { transmute("Rust") }; - //~^ ERROR Transmute to &[u8] from &'static str detected - - let _: &[u8] = unsafe { mem::transmute("Rust") }; - //~^ ERROR Transmute to &[u8] from &'static str detected -} diff --git a/tests/compiletest/plugin/lib.rs b/tests/compiletest/plugin/lib.rs index d3466c57b9b..d8298ea5c7b 100644 --- a/tests/compiletest/plugin/lib.rs +++ b/tests/compiletest/plugin/lib.rs @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate compiletest_helper; +#[macro_use] +extern crate deny_public_fields; #[test] fn compile_test() { |