diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-30 12:03:34 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-30 12:03:34 -0800 |
| commit | 6ea5fb8a6d3131931dd70d45dc4d4f0b1e26cd01 (patch) | |
| tree | f01f397c5b39e7169146fa8ab3b920f29c946619 | |
| parent | 62a8462ba48060d9c51765c3ac3f26b03d4fe1ae (diff) | |
| parent | 39a8c23c0b2aab6fba24a2facc2a565d6b9faa1f (diff) | |
| download | rust-6ea5fb8a6d3131931dd70d45dc4d4f0b1e26cd01.tar.gz rust-6ea5fb8a6d3131931dd70d45dc4d4f0b1e26cd01.zip | |
rollup merge of #21765: P1start/non-ascii-style-lints
An alternative to #21749. This also refactors the naming lint code a little bit and slightly rephrases some warnings (`uppercase` → `upper case`). Closes #21735.
| -rw-r--r-- | src/librustc/lint/builtin.rs | 113 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-17718-const-naming.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/lint-group-style.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/lint-non-uppercase-statics.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/match-static-const-lc.rs | 6 | ||||
| -rw-r--r-- | src/test/run-pass/snake-case-no-lowercase-equivalent.rs | 17 |
6 files changed, 90 insertions, 52 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 2248562352d..98b6d4bd88e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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); } _ => {} } diff --git a/src/test/compile-fail/issue-17718-const-naming.rs b/src/test/compile-fail/issue-17718-const-naming.rs index 15f66493f88..06719e2756b 100644 --- a/src/test/compile-fail/issue-17718-const-naming.rs +++ b/src/test/compile-fail/issue-17718-const-naming.rs @@ -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() {} diff --git a/src/test/compile-fail/lint-group-style.rs b/src/test/compile-fail/lint-group-style.rs index 24d16bcaafc..59ab5be1572 100644 --- a/src/test/compile-fail/lint-group-style.rs +++ b/src/test/compile-fail/lint-group-style.rs @@ -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 { diff --git a/src/test/compile-fail/lint-non-uppercase-statics.rs b/src/test/compile-fail/lint-non-uppercase-statics.rs index 10475f967d7..e1fbc73bbed 100644 --- a/src/test/compile-fail/lint-non-uppercase-statics.rs +++ b/src/test/compile-fail/lint-non-uppercase-statics.rs @@ -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() { } diff --git a/src/test/compile-fail/match-static-const-lc.rs b/src/test/compile-fail/match-static-const-lc.rs index 345c4aa69a7..04b234d8db7 100644 --- a/src/test/compile-fail/match-static-const-lc.rs +++ b/src/test/compile-fail/match-static-const-lc.rs @@ -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); diff --git a/src/test/run-pass/snake-case-no-lowercase-equivalent.rs b/src/test/run-pass/snake-case-no-lowercase-equivalent.rs new file mode 100644 index 00000000000..2220761a026 --- /dev/null +++ b/src/test/run-pass/snake-case-no-lowercase-equivalent.rs @@ -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() {} |
