diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2017-02-16 09:18:02 +0100 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2017-02-16 18:37:14 +0100 |
commit | 3eed8a91a1183e22b69b1be48ad97a253bc1dc0a (patch) | |
tree | ba6b0b4740560d40445e2a817397a674ec1f8637 /components/script_plugins/utils.rs | |
parent | 84a44a401424852bc44ef5e751e84544ed892e70 (diff) | |
download | servo-3eed8a91a1183e22b69b1be48ad97a253bc1dc0a.tar.gz servo-3eed8a91a1183e22b69b1be48ad97a253bc1dc0a.zip |
Move script lints to script_plugins
The plugins crate now just allows to hook into clippy from a single crate.
Diffstat (limited to 'components/script_plugins/utils.rs')
-rw-r--r-- | components/script_plugins/utils.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/components/script_plugins/utils.rs b/components/script_plugins/utils.rs new file mode 100644 index 00000000000..50ff2a959a9 --- /dev/null +++ b/components/script_plugins/utils.rs @@ -0,0 +1,73 @@ +/* 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::def_id::DefId; +use rustc::lint::{LateContext, LintContext}; +use syntax::ast; +use syntax::codemap::{ExpnFormat, Span}; +use syntax::ptr::P; + +/// Matches a type with a provided string, and returns its type parameters if successful +pub fn match_ty_unwrap<'a>(ty: &'a ast::Ty, segments: &[&str]) -> Option<&'a [P<ast::Ty>]> { + match ty.node { + ast::TyKind::Path(_, ast::Path { segments: ref seg, .. }) => { + // So hir::Path isn't the full path, just the tokens that were provided. + // I could muck around with the maps and find the full path + // however the more efficient way is to simply reverse the iterators and zip them + // which will compare them in reverse until one of them runs out of segments + if seg.iter().rev().zip(segments.iter().rev()).all(|(a, b)| &*a.identifier.name.as_str() == *b) { + match seg.last() { + Some(&ast::PathSegment { parameters: Some(ref params), .. }) => { + match **params { + ast::PathParameters::AngleBracketed(ref a) => Some(&a.types), + + // `Foo(A,B) -> C` + ast::PathParameters::Parenthesized(_) => None, + } + } + Some(&ast::PathSegment { parameters: None, .. }) => Some(&[]), + None => None, + } + } else { + None + } + }, + _ => None + } +} + +/// check if a DefId's path matches the given absolute type path +/// usage e.g. with +/// `match_def_path(cx, id, &["core", "option", "Option"])` +pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool { + let krate = &cx.tcx.crate_name(def_id.krate); + if krate != &path[0] { + return false; + } + + let path = &path[1..]; + let other = cx.tcx.def_path(def_id).data; + + if other.len() != path.len() { + return false; + } + + other.into_iter() + .map(|e| e.data) + .zip(path) + .all(|(nm, p)| &*nm.as_interned_str() == *p) +} + +pub fn in_derive_expn(cx: &LateContext, span: Span) -> bool { + cx.sess().codemap().with_expn_info(span.expn_id, + |info| { + if let Some(i) = info { + if let ExpnFormat::MacroAttribute(n) = i.callee.format { + if n.as_str().contains("derive") { + true + } else { false } + } else { false } + } else { false } + }) +} |