Make the naming lints only warn on names with upper/lowercase equivalents

Closes #21735.
This commit is contained in:
P1start 2014-12-06 13:17:30 +13:00
parent c5961ad06d
commit 39a8c23c0b
6 changed files with 90 additions and 52 deletions

View File

@ -937,6 +937,34 @@ declare_lint! {
pub struct NonSnakeCase;
impl NonSnakeCase {
fn to_snake_case(mut str: &str) -> String {
let mut words = vec![];
// Preserve leading underscores
str = str.trim_left_matches(|&mut: c: char| {
if c == '_' {
words.push(String::new());
true
} else { false }
});
for s in str.split('_') {
let mut last_upper = false;
let mut buf = String::new();
if s.is_empty() { continue; }
for ch in s.chars() {
if !buf.is_empty() && buf != "'"
&& ch.is_uppercase()
&& !last_upper {
words.push(buf);
buf = String::new();
}
last_upper = ch.is_uppercase();
buf.push(ch.to_lowercase());
}
words.push(buf);
}
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);
@ -947,41 +975,28 @@ impl NonSnakeCase {
let mut allow_underscore = true;
ident.chars().all(|c| {
allow_underscore = match c {
c if c.is_lowercase() || c.is_numeric() => true,
'_' if allow_underscore => false,
'_' if !allow_underscore => return false,
'_' => false,
c if !c.is_uppercase() => true,
_ => return false,
};
true
})
}
fn to_snake_case(str: &str) -> String {
let mut words = vec![];
for s in str.split('_') {
let mut last_upper = false;
let mut buf = String::new();
if s.is_empty() { continue; }
for ch in s.chars() {
if !buf.is_empty() && buf != "'"
&& ch.is_uppercase()
&& !last_upper {
words.push(buf);
buf = String::new();
}
last_upper = ch.is_uppercase();
buf.push(ch.to_lowercase());
}
words.push(buf);
}
words.connect("_")
}
let s = token::get_ident(ident);
if !is_snake_case(ident) {
cx.span_lint(NON_SNAKE_CASE, span,
&format!("{} `{}` should have a snake case name such as `{}`",
sort, s, to_snake_case(s.get()))[]);
let sc = NonSnakeCase::to_snake_case(s.get());
if sc != s.get() {
cx.span_lint(NON_SNAKE_CASE, span,
&*format!("{} `{}` should have a snake case name such as `{}`",
sort, s, sc));
} else {
cx.span_lint(NON_SNAKE_CASE, span,
&*format!("{} `{}` should have a snake case name",
sort, s));
}
}
}
}
@ -1049,6 +1064,26 @@ declare_lint! {
#[derive(Copy)]
pub struct NonUpperCaseGlobals;
impl NonUpperCaseGlobals {
fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
let s = token::get_ident(ident);
if s.get().chars().any(|c| c.is_lowercase()) {
let uc: String = NonSnakeCase::to_snake_case(s.get()).chars()
.map(|c| c.to_uppercase()).collect();
if uc != s.get() {
cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
format!("{} `{}` should have an upper case name such as `{}`",
sort, s, uc).as_slice());
} else {
cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
format!("{} `{}` should have an upper case name",
sort, s).as_slice());
}
}
}
}
impl LintPass for NonUpperCaseGlobals {
fn get_lints(&self) -> LintArray {
lint_array!(NON_UPPER_CASE_GLOBALS)
@ -1057,19 +1092,11 @@ impl LintPass for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
match it.node {
// only check static constants
ast::ItemStatic(_, ast::MutImmutable, _) |
ast::ItemStatic(_, ast::MutImmutable, _) => {
NonUpperCaseGlobals::check_upper_case(cx, "static constant", it.ident, it.span);
}
ast::ItemConst(..) => {
let s = token::get_ident(it.ident);
// check for lowercase letters rather than non-uppercase
// ones (some scripts don't have a concept of
// upper/lowercase)
if s.get().chars().any(|c| c.is_lowercase()) {
cx.span_lint(NON_UPPER_CASE_GLOBALS, it.span,
&format!("static constant `{}` should have an uppercase name \
such as `{}`",
s.get(), &s.get().chars().map(|c| c.to_uppercase())
.collect::<String>()[])[]);
}
NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident, it.span);
}
_ => {}
}
@ -1079,14 +1106,8 @@ impl LintPass for NonUpperCaseGlobals {
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
let s = token::get_ident(path1.node);
if s.get().chars().any(|c| c.is_lowercase()) {
cx.span_lint(NON_UPPER_CASE_GLOBALS, path1.span,
&format!("static constant in pattern `{}` should have an uppercase \
name such as `{}`",
s.get(), &s.get().chars().map(|c| c.to_uppercase())
.collect::<String>()[])[]);
}
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path1.node, p.span);
}
_ => {}
}

View File

@ -11,7 +11,7 @@
#[deny(warnings)]
const foo: isize = 3;
//~^ ERROR: should have an uppercase name such as
//~^ ERROR: should have an upper case name such as
//~^^ ERROR: constant item is never used
fn main() {}

View File

@ -24,7 +24,7 @@ mod test {
mod bad {
fn CamelCase() {} //~ ERROR function `CamelCase` should have a snake case name
static bad: isize = 1; //~ ERROR static constant `bad` should have an uppercase name
static bad: isize = 1; //~ ERROR static constant `bad` should have an upper case name
}
mod warn {

View File

@ -11,6 +11,6 @@
#![forbid(non_upper_case_globals)]
#![allow(dead_code)]
static foo: isize = 1; //~ ERROR static constant `foo` should have an uppercase name such as `FOO`
static foo: isize = 1; //~ ERROR static constant `foo` should have an upper case name such as `FOO`
fn main() { }

View File

@ -19,7 +19,7 @@ pub const a : isize = 97;
fn f() {
let r = match (0,0) {
(0, a) => 0,
//~^ ERROR static constant in pattern `a` should have an uppercase name such as `A`
//~^ ERROR constant in pattern `a` should have an upper case name such as `A`
(x, y) => 1 + x + y,
};
assert!(r == 1);
@ -34,7 +34,7 @@ fn g() {
use self::m::aha;
let r = match (0,0) {
(0, aha) => 0,
//~^ ERROR static constant in pattern `aha` should have an uppercase name such as `AHA`
//~^ ERROR constant in pattern `aha` should have an upper case name such as `AHA`
(x, y) => 1 + x + y,
};
assert!(r == 1);
@ -48,7 +48,7 @@ fn h() {
use self::n::OKAY as not_okay;
let r = match (0,0) {
(0, not_okay) => 0,
//~^ ERROR static constant in pattern `not_okay` should have an uppercase name such as `NOT_OKAY`
//~^ ERROR constant in pattern `not_okay` should have an upper case name such as `NOT_OKAY`
(x, y) => 1 + x + y,
};
assert!(r == 1);

View File

@ -0,0 +1,17 @@
// Copyright 2014 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.
#![feature(non_ascii_idents)]
#![deny(non_snake_case)]
// This name is neither upper nor lower case
fn () {}
fn main() {}