Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
break up lints.rs into separate files
- Loading branch information
Showing
9 changed files
with
430 additions
and
378 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* 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 syntax::{ast, ast_util}; | ||
use rustc::lint::{Context, LintPass, LintArray, Level}; | ||
use rustc::middle::{ty, def}; | ||
use rustc::middle::typeck::astconv::AstConv; | ||
|
||
use utils::match_lang_ty; | ||
|
||
declare_lint!(INHERITANCE_INTEGRITY, Deny, | ||
"Ensures that struct fields are properly laid out for inheritance to work") | ||
|
||
/// Lint for ensuring proper layout of DOM structs | ||
/// | ||
/// A DOM struct must have one Reflector field or one field | ||
/// which itself is a DOM struct (in which case it must be the first field). | ||
pub struct InheritancePass; | ||
|
||
impl LintPass for InheritancePass { | ||
fn get_lints(&self) -> LintArray { | ||
lint_array!(INHERITANCE_INTEGRITY) | ||
} | ||
|
||
fn check_struct_def(&mut self, cx: &Context, def: &ast::StructDef, _i: ast::Ident, _gen: &ast::Generics, id: ast::NodeId) { | ||
// Lints are run post expansion, so it's fine to use | ||
// #[_dom_struct_marker] here without also checking for #[dom_struct] | ||
if ty::has_attr(cx.tcx, ast_util::local_def(id), "_dom_struct_marker") { | ||
// Find the reflector, if any | ||
let reflector_span = def.fields.iter().enumerate() | ||
.find(|&(ctr, f)| { | ||
if match_lang_ty(cx, &*f.node.ty, "reflector") { | ||
if ctr > 0 { | ||
cx.span_lint(INHERITANCE_INTEGRITY, f.span, | ||
"The Reflector should be the first field of the DOM struct"); | ||
} | ||
return true; | ||
} | ||
false | ||
}) | ||
.map(|(_, f)| f.span); | ||
// Find all #[dom_struct] fields | ||
let dom_spans: Vec<_> = def.fields.iter().enumerate().filter_map(|(ctr, f)| { | ||
if let ast::TyPath(_, _, ty_id) = f.node.ty.node { | ||
if let Some(def::DefTy(def_id, _)) = cx.tcx.def_map.borrow().get(&ty_id).cloned() { | ||
if ty::has_attr(cx.tcx, def_id, "_dom_struct_marker") { | ||
// If the field is not the first, it's probably | ||
// being misused (a) | ||
if ctr > 0 { | ||
cx.span_lint(INHERITANCE_INTEGRITY, f.span, | ||
"Bare DOM structs should only be used as the first field of a \ | ||
DOM struct. Consider using JS<T> instead."); | ||
} | ||
return Some(f.span) | ||
} | ||
} | ||
} | ||
None | ||
}).collect(); | ||
|
||
// We should not have both a reflector and a dom struct field | ||
if let Some(sp) = reflector_span { | ||
if dom_spans.len() > 0 { | ||
cx.span_lint(INHERITANCE_INTEGRITY, cx.tcx.map.expect_item(id).span, | ||
"This DOM struct has both Reflector and bare DOM struct members"); | ||
if cx.current_level(INHERITANCE_INTEGRITY) != Level::Allow { | ||
let sess = cx.sess(); | ||
sess.span_note(sp, "Reflector found here"); | ||
for span in dom_spans.iter() { | ||
sess.span_note(*span, "Bare DOM struct found here"); | ||
} | ||
} | ||
} | ||
// Nor should we have more than one dom struct field | ||
} else if dom_spans.len() > 1 { | ||
cx.span_lint(INHERITANCE_INTEGRITY, cx.tcx.map.expect_item(id).span, | ||
"This DOM struct has multiple DOM struct members, only one is allowed"); | ||
if cx.current_level(INHERITANCE_INTEGRITY) != Level::Allow { | ||
for span in dom_spans.iter() { | ||
cx.sess().span_note(*span, "Bare DOM struct found here"); | ||
} | ||
} | ||
} else if dom_spans.len() == 0 { | ||
cx.span_lint(INHERITANCE_INTEGRITY, cx.tcx.map.expect_item(id).span, | ||
"This DOM struct has no reflector or parent DOM struct"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* 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/. */ | ||
|
||
pub mod inheritance_integrity; | ||
pub mod privatize; | ||
pub mod str_to_string; | ||
pub mod transmute_type; | ||
pub mod unrooted_must_root; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* 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 syntax::{ast, ast_util}; | ||
use syntax::ast::Public; | ||
use syntax::attr::AttrMetaMethods; | ||
use rustc::lint::{Context, LintPass, LintArray}; | ||
use rustc::middle::ty; | ||
use rustc::middle::typeck::astconv::AstConv; | ||
|
||
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 private fields | ||
pub struct PrivatizePass; | ||
|
||
impl LintPass for PrivatizePass { | ||
fn get_lints(&self) -> LintArray { | ||
lint_array!(PRIVATIZE) | ||
} | ||
|
||
fn check_struct_def(&mut self, cx: &Context, def: &ast::StructDef, _i: ast::Ident, _gen: &ast::Generics, id: ast::NodeId) { | ||
if ty::has_attr(cx.tcx, ast_util::local_def(id), "privatize") { | ||
for field in def.fields.iter() { | ||
match field.node { | ||
ast::StructField_ { kind: ast::NamedField(ident, visibility), .. } if visibility == Public => { | ||
cx.span_lint(PRIVATIZE, field.span, | ||
format!("Field {} is public where only private fields are allowed", ident.name).as_slice()); | ||
} | ||
_ => {} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* 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 syntax::ast; | ||
use rustc::lint::{Context, LintPass, LintArray}; | ||
use rustc::middle::ty::expr_ty; | ||
use rustc::middle::ty; | ||
use rustc::middle::typeck::astconv::AstConv; | ||
|
||
declare_lint!(STR_TO_STRING, Deny, | ||
"Warn when a String could use into_string() instead of to_string()") | ||
|
||
/// Prefer str.into_string() over str.to_string() | ||
/// | ||
/// The latter creates a `Formatter` and is 5x slower than the former | ||
pub struct StrToStringPass; | ||
|
||
impl LintPass for StrToStringPass { | ||
fn get_lints(&self) -> LintArray { | ||
lint_array!(STR_TO_STRING) | ||
} | ||
|
||
fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) { | ||
match expr.node { | ||
ast::ExprMethodCall(ref method, _, ref args) | ||
if method.node.as_str() == "to_string" | ||
&& is_str(cx, &*args[0]) => { | ||
cx.span_lint(STR_TO_STRING, expr.span, | ||
"str.into_string() is more efficient than str.to_string(), please use it instead"); | ||
}, | ||
_ => () | ||
} | ||
|
||
fn is_str(cx: &Context, expr: &ast::Expr) -> bool { | ||
fn walk_ty<'t>(ty: ty::t) -> ty::t { | ||
match ty::get(ty).sty { | ||
ty::ty_ptr(ref tm) | ty::ty_rptr(_, ref tm) => walk_ty(tm.ty), | ||
_ => ty | ||
} | ||
} | ||
match ty::get(walk_ty(expr_ty(cx.tcx, expr))).sty { | ||
ty::ty_str => true, | ||
_ => false | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* 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 syntax::ast; | ||
use syntax::attr::AttrMetaMethods; | ||
use rustc::lint::{Context, LintPass, LintArray}; | ||
use rustc::middle::ty::expr_ty; | ||
use rustc::middle::typeck::astconv::AstConv; | ||
use rustc::util::ppaux::Repr; | ||
|
||
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) | ||
} | ||
|
||
fn check_expr(&mut self, cx: &Context, ex: &ast::Expr) { | ||
match ex.node { | ||
ast::ExprCall(ref expr, ref args) => { | ||
match expr.node { | ||
ast::ExprPath(ref path) => { | ||
if path.segments.last() | ||
.map_or(false, |ref segment| segment.identifier.name.as_str() == "transmute") | ||
&& args.len() == 1 { | ||
let tcx = cx.tcx(); | ||
cx.span_lint(TRANSMUTE_TYPE_LINT, ex.span, | ||
format!("Transmute to {} from {} detected", | ||
expr_ty(tcx, ex).repr(tcx), | ||
expr_ty(tcx, &**args.get(0).unwrap()).repr(tcx) | ||
).as_slice()); | ||
} | ||
} | ||
_ => {} | ||
} | ||
} | ||
_ => {} | ||
} | ||
} | ||
} |
Oops, something went wrong.
7ac58f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saw approval from Manishearth
at ajnirp@7ac58f2
7ac58f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merging wenderen/servo/separate-lints = 7ac58f2 into auto
7ac58f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wenderen/servo/separate-lints = 7ac58f2 merged ok, testing candidate = 685dec1
7ac58f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all tests pass:
success: http://build.servo.org/builders/linux1/builds/441
success: http://build.servo.org/builders/linux2/builds/440
success: http://build.servo.org/builders/android/builds/476
success: http://build.servo.org/builders/mac1/builds/657
success: http://build.servo.org/builders/mac2/builds/658
7ac58f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fast-forwarding master to auto = 685dec1