Lint non-snake-case crate names

Passing a non-snake-case name to #![crate_name] or --crate-name will now yield a
warning from the `non_snake_case` lint.
This commit is contained in:
P1start 2015-04-18 13:39:10 +12:00
parent bd968a1d65
commit c163f89310
3 changed files with 65 additions and 22 deletions

View file

@ -910,9 +910,8 @@ fn to_snake_case(mut str: &str) -> String {
words.connect("_")
}
fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_snake_case(ident: ast::Ident) -> bool {
let ident = token::get_ident(ident);
fn check_snake_case(&self, cx: &Context, sort: &str, name: &str, span: Option<Span>) {
fn is_snake_case(ident: &str) -> bool {
if ident.is_empty() {
return true;
}
@ -931,18 +930,18 @@ fn is_snake_case(ident: ast::Ident) -> bool {
})
}
let s = token::get_ident(ident);
if !is_snake_case(ident) {
let sc = NonSnakeCase::to_snake_case(&s);
if sc != &s[..] {
cx.span_lint(NON_SNAKE_CASE, span,
&*format!("{} `{}` should have a snake case name such as `{}`",
sort, s, sc));
if !is_snake_case(name) {
let sc = NonSnakeCase::to_snake_case(name);
let msg = if sc != name {
format!("{} `{}` should have a snake case name such as `{}`",
sort, name, sc)
} else {
cx.span_lint(NON_SNAKE_CASE, span,
&*format!("{} `{}` should have a snake case name",
sort, s));
format!("{} `{}` should have a snake case name",
sort, name)
};
match span {
Some(span) => cx.span_lint(NON_SNAKE_CASE, span, &msg),
None => cx.lint(NON_SNAKE_CASE, &msg),
}
}
}
@ -953,21 +952,31 @@ fn get_lints(&self) -> LintArray {
lint_array!(NON_SNAKE_CASE)
}
fn check_crate(&mut self, cx: &Context, cr: &ast::Crate) {
let attr_crate_name = cr.attrs.iter().find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(ref name) = cx.tcx.sess.opts.crate_name {
self.check_snake_case(cx, "crate", name, None);
} else if let Some((attr, ref name)) = attr_crate_name {
self.check_snake_case(cx, "crate", name, Some(attr.span));
}
}
fn check_fn(&mut self, cx: &Context,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, id: ast::NodeId) {
match fk {
visit::FkMethod(ident, _, _) => match method_context(cx, id, span) {
MethodContext::PlainImpl => {
self.check_snake_case(cx, "method", ident, span)
self.check_snake_case(cx, "method", &token::get_ident(ident), Some(span))
},
MethodContext::TraitDefaultImpl => {
self.check_snake_case(cx, "trait method", ident, span)
self.check_snake_case(cx, "trait method", &token::get_ident(ident), Some(span))
},
_ => (),
},
visit::FkItemFn(ident, _, _, _, _) => {
self.check_snake_case(cx, "function", ident, span)
self.check_snake_case(cx, "function", &token::get_ident(ident), Some(span))
},
_ => (),
}
@ -975,25 +984,27 @@ fn check_fn(&mut self, cx: &Context,
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
if let ast::ItemMod(_) = it.node {
self.check_snake_case(cx, "module", it.ident, it.span);
self.check_snake_case(cx, "module", &token::get_ident(it.ident), Some(it.span));
}
}
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
if let ast::MethodTraitItem(_, None) = trait_item.node {
self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
self.check_snake_case(cx, "trait method", &token::get_ident(trait_item.ident),
Some(trait_item.span));
}
}
fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span);
self.check_snake_case(cx, "lifetime", &token::get_ident(t.lifetime.name.ident()),
Some(t.lifetime.span));
}
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
if let &ast::PatIdent(_, ref path1, _) = &p.node {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
if let Some(def::DefLocal(_)) = def {
self.check_snake_case(cx, "variable", path1.node, p.span);
self.check_snake_case(cx, "variable", &token::get_ident(path1.node), Some(p.span));
}
}
}
@ -1002,7 +1013,8 @@ fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
_: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
for sf in &s.fields {
if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
self.check_snake_case(cx, "structure field", ident, sf.span);
self.check_snake_case(cx, "structure field", &token::get_ident(ident),
Some(sf.span));
}
}
}

View file

@ -0,0 +1,16 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --crate-name NonSnakeCase
// error-pattern: crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
#![deny(non_snake_case)]
fn main() {}

View file

@ -0,0 +1,15 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "NonSnakeCase"]
//~^ ERROR crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
#![deny(non_snake_case)]
fn main() {}