From 2535804aa0bf2f0b7f230793ece8a5b39b980ec7 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 21 Dec 2017 11:22:18 +0000 Subject: [PATCH 1/4] Allow underscores in camel-case between non-alphabetic characters --- src/Cargo.lock | 8 ++++++++ src/librustc_lint/Cargo.toml | 4 +++- src/librustc_lint/bad_style.rs | 32 +++++++++++++++++++++----------- src/librustc_lint/lib.rs | 3 +++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index c22187ee13e8e..26b70f63d6589 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -967,6 +967,11 @@ name = "lazy_static" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazycell" version = "0.5.1" @@ -1863,7 +1868,9 @@ dependencies = [ name = "rustc_lint" version = "0.0.0" dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_const_eval 0.0.0", "syntax 0.0.0", @@ -2813,6 +2820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e03098e8e719c92b7794515dfd5c1724e2b12f5ce1788e61cfa4663f82eba8d8" "checksum languageserver-types 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "773e175c945800aeea4c21c04090bcb9db987b1a566ad9c6f569972299950e3e" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" "checksum libgit2-sys 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "6f74b4959cef96898f5123148724fc7dee043b9a6b99f219d948851bfbe53cb2" diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index cebf52d5af7a9..2cc1827f518da 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -6,7 +6,7 @@ version = "0.0.0" [lib] name = "rustc_lint" path = "lib.rs" -crate-type = ["dylib"] +crate-types = ["rlib", "dylib"] test = false [dependencies] @@ -15,3 +15,5 @@ rustc = { path = "../librustc" } rustc_const_eval = { path = "../librustc_const_eval" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } +lazy_static = "1.0" +regex = "0.2.3" diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index d14a6943fc112..09194d5c7c4ae 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -21,6 +21,12 @@ use syntax_pos::Span; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::FnKind; +use regex::Regex; + +lazy_static! { + static ref ALPHABETIC_UNDERSCORE: Regex = Regex::new("([[:alpha:]])_([[:alpha:]])").unwrap(); +} + #[derive(PartialEq)] pub enum MethodLateContext { TraitAutoImpl, @@ -62,20 +68,24 @@ impl NonCamelCaseTypes { // start with a non-lowercase letter rather than non-uppercase // ones (some scripts don't have a concept of upper/lowercase) - !name.is_empty() && !name.chars().next().unwrap().is_lowercase() && !name.contains('_') + !name.is_empty() && !name.chars().next().unwrap().is_lowercase() && + !ALPHABETIC_UNDERSCORE.is_match(name) } fn to_camel_case(s: &str) -> String { - s.split('_') - .flat_map(|word| { - word.chars().enumerate().map(|(i, c)| if i == 0 { - c.to_uppercase().collect::() - } else { - c.to_lowercase().collect() - }) - }) - .collect::>() - .concat() + let s = s.split('_') + .map(|word| { + word.chars().enumerate().map(|(i, c)| if i == 0 { + c.to_uppercase().collect::() + } else { + c.to_lowercase().collect() + }) + .collect::>() + .concat() + }) + .collect::>() + .join("_"); + ALPHABETIC_UNDERSCORE.replace_all(s.as_str(), "$1$2").to_string() } if !is_camel_case(name) { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 8b41dd62742ce..d285ac91e9fe5 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,6 +41,9 @@ extern crate rustc; extern crate log; extern crate rustc_const_eval; extern crate syntax_pos; +#[macro_use] +extern crate lazy_static; +extern crate regex; use rustc::lint; use rustc::middle; From e4c02e551b6c6c94cafc09d4db0b493836673292 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 21 Dec 2017 13:12:36 +0000 Subject: [PATCH 2/4] Adjust the rules for underscores --- src/librustc_lint/bad_style.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 09194d5c7c4ae..123dbe807fb09 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -24,7 +24,8 @@ use rustc::hir::intravisit::FnKind; use regex::Regex; lazy_static! { - static ref ALPHABETIC_UNDERSCORE: Regex = Regex::new("([[:alpha:]])_([[:alpha:]])").unwrap(); + static ref ALPHABETIC_UNDERSCORE: Regex = + Regex::new("([[:alpha:]])_+|_+([[:alpha:]])").unwrap(); } #[derive(PartialEq)] @@ -69,11 +70,12 @@ impl NonCamelCaseTypes { // start with a non-lowercase letter rather than non-uppercase // ones (some scripts don't have a concept of upper/lowercase) !name.is_empty() && !name.chars().next().unwrap().is_lowercase() && - !ALPHABETIC_UNDERSCORE.is_match(name) + !name.contains("__") && !ALPHABETIC_UNDERSCORE.is_match(name) } fn to_camel_case(s: &str) -> String { - let s = s.split('_') + let s = s.trim_matches('_') + .split('_') .map(|word| { word.chars().enumerate().map(|(i, c)| if i == 0 { c.to_uppercase().collect::() @@ -83,6 +85,7 @@ impl NonCamelCaseTypes { .collect::>() .concat() }) + .filter(|x| !x.is_empty()) .collect::>() .join("_"); ALPHABETIC_UNDERSCORE.replace_all(s.as_str(), "$1$2").to_string() From c1aa017645925ef1fd80c0d69b08ebca532e6a38 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 21 Dec 2017 13:12:58 +0000 Subject: [PATCH 3/4] Add tests --- src/test/compile-fail/lint-non-camel-case-types.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs index f6d3d62d0bf75..5dcdf3a863f87 100644 --- a/src/test/compile-fail/lint-non-camel-case-types.rs +++ b/src/test/compile-fail/lint-non-camel-case-types.rs @@ -45,4 +45,12 @@ struct foo7 { type __ = isize; //~ ERROR type `__` should have a camel case name such as `CamelCase` +struct X86_64; + +struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64` + +struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123` + +struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3` + fn main() { } From 3dff918c6c3748104bf83db1b27fd13d51d587be Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 2 Jan 2018 01:06:17 +0000 Subject: [PATCH 4/4] Remove dependency on regex --- src/Cargo.lock | 8 ----- src/librustc_lint/Cargo.toml | 4 +-- src/librustc_lint/bad_style.rs | 55 ++++++++++++++++++++-------------- src/librustc_lint/lib.rs | 3 -- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 26b70f63d6589..c22187ee13e8e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -967,11 +967,6 @@ name = "lazy_static" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lazy_static" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazycell" version = "0.5.1" @@ -1868,9 +1863,7 @@ dependencies = [ name = "rustc_lint" version = "0.0.0" dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_const_eval 0.0.0", "syntax 0.0.0", @@ -2820,7 +2813,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e03098e8e719c92b7794515dfd5c1724e2b12f5ce1788e61cfa4663f82eba8d8" "checksum languageserver-types 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "773e175c945800aeea4c21c04090bcb9db987b1a566ad9c6f569972299950e3e" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" "checksum libgit2-sys 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "6f74b4959cef96898f5123148724fc7dee043b9a6b99f219d948851bfbe53cb2" diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 2cc1827f518da..cebf52d5af7a9 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -6,7 +6,7 @@ version = "0.0.0" [lib] name = "rustc_lint" path = "lib.rs" -crate-types = ["rlib", "dylib"] +crate-type = ["dylib"] test = false [dependencies] @@ -15,5 +15,3 @@ rustc = { path = "../librustc" } rustc_const_eval = { path = "../librustc_const_eval" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -lazy_static = "1.0" -regex = "0.2.3" diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 123dbe807fb09..f089ce8f06533 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -21,13 +21,6 @@ use syntax_pos::Span; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::FnKind; -use regex::Regex; - -lazy_static! { - static ref ALPHABETIC_UNDERSCORE: Regex = - Regex::new("([[:alpha:]])_+|_+([[:alpha:]])").unwrap(); -} - #[derive(PartialEq)] pub enum MethodLateContext { TraitAutoImpl, @@ -60,6 +53,10 @@ pub struct NonCamelCaseTypes; impl NonCamelCaseTypes { fn check_case(&self, cx: &LateContext, sort: &str, name: ast::Name, span: Span) { + fn char_has_case(c: char) -> bool { + c.is_lowercase() || c.is_uppercase() + } + fn is_camel_case(name: ast::Name) -> bool { let name = name.as_str(); if name.is_empty() { @@ -70,25 +67,37 @@ impl NonCamelCaseTypes { // start with a non-lowercase letter rather than non-uppercase // ones (some scripts don't have a concept of upper/lowercase) !name.is_empty() && !name.chars().next().unwrap().is_lowercase() && - !name.contains("__") && !ALPHABETIC_UNDERSCORE.is_match(name) + !name.contains("__") && !name.chars().collect::>().windows(2).any(|pair| { + // contains a capitalisable character followed by, or preceded by, an underscore + char_has_case(pair[0]) && pair[1] == '_' || + char_has_case(pair[1]) && pair[0] == '_' + }) } fn to_camel_case(s: &str) -> String { - let s = s.trim_matches('_') - .split('_') - .map(|word| { - word.chars().enumerate().map(|(i, c)| if i == 0 { - c.to_uppercase().collect::() - } else { - c.to_lowercase().collect() - }) - .collect::>() - .concat() - }) - .filter(|x| !x.is_empty()) - .collect::>() - .join("_"); - ALPHABETIC_UNDERSCORE.replace_all(s.as_str(), "$1$2").to_string() + s.trim_matches('_') + .split('_') + .map(|word| { + word.chars().enumerate().map(|(i, c)| if i == 0 { + c.to_uppercase().collect::() + } else { + c.to_lowercase().collect() + }) + .collect::>() + .concat() + }) + .filter(|x| !x.is_empty()) + .collect::>() + .iter().fold((String::new(), None), |(acc, prev): (String, Option<&String>), next| { + // separate two components with an underscore if their boundary cannot + // be distinguished using a uppercase/lowercase case distinction + let join = if let Some(prev) = prev { + let l = prev.chars().last().unwrap(); + let f = next.chars().next().unwrap(); + !char_has_case(l) && !char_has_case(f) + } else { false }; + (acc + if join { "_" } else { "" } + next, Some(next)) + }).0 } if !is_camel_case(name) { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d285ac91e9fe5..8b41dd62742ce 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,9 +41,6 @@ extern crate rustc; extern crate log; extern crate rustc_const_eval; extern crate syntax_pos; -#[macro_use] -extern crate lazy_static; -extern crate regex; use rustc::lint; use rustc::middle;