mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 06:28:42 +00:00
first unicode lint: zero_width_space
This commit is contained in:
parent
ad8841c20b
commit
23caf3cccc
4 changed files with 74 additions and 0 deletions
|
@ -29,6 +29,7 @@ Lints included in this crate:
|
||||||
- `redundant_closure` warns on creating a closure where none is needed, e.g. `|x| foo(x)`, where `foo` can be used directly
|
- `redundant_closure` warns on creating a closure where none is needed, e.g. `|x| foo(x)`, where `foo` can be used directly
|
||||||
- `inline_always`: Warns on `#[inline(always)]`, because in most cases it is a bad idea
|
- `inline_always`: Warns on `#[inline(always)]`, because in most cases it is a bad idea
|
||||||
- `collapsible_if`: Warns on cases where two nested `if`-expressions can be collapsed into one, e.g. `if x { if y { foo() } }` can be written as `if x && y { foo() }`
|
- `collapsible_if`: Warns on cases where two nested `if`-expressions can be collapsed into one, e.g. `if x { if y { foo() } }` can be written as `if x && y { foo() }`
|
||||||
|
- `zero_width_space`: Warns on encountering a unicode zero-width space
|
||||||
|
|
||||||
To use, add the following lines to your Cargo.toml:
|
To use, add the following lines to your Cargo.toml:
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub mod mut_mut;
|
||||||
pub mod len_zero;
|
pub mod len_zero;
|
||||||
pub mod attrs;
|
pub mod attrs;
|
||||||
pub mod collapsible_if;
|
pub mod collapsible_if;
|
||||||
|
pub mod unicode;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
#[plugin_registrar]
|
#[plugin_registrar]
|
||||||
|
@ -49,6 +50,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
reg.register_lint_pass(box misc::CmpOwned as LintPassObject);
|
reg.register_lint_pass(box misc::CmpOwned as LintPassObject);
|
||||||
reg.register_lint_pass(box attrs::AttrPass as LintPassObject);
|
reg.register_lint_pass(box attrs::AttrPass as LintPassObject);
|
||||||
reg.register_lint_pass(box collapsible_if::CollapsibleIf as LintPassObject);
|
reg.register_lint_pass(box collapsible_if::CollapsibleIf as LintPassObject);
|
||||||
|
reg.register_lint_pass(box unicode::Unicode as LintPassObject);
|
||||||
|
|
||||||
reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
|
reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
|
||||||
misc::SINGLE_MATCH, misc::STR_TO_STRING,
|
misc::SINGLE_MATCH, misc::STR_TO_STRING,
|
||||||
|
@ -67,5 +69,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
len_zero::LEN_WITHOUT_IS_EMPTY,
|
len_zero::LEN_WITHOUT_IS_EMPTY,
|
||||||
attrs::INLINE_ALWAYS,
|
attrs::INLINE_ALWAYS,
|
||||||
collapsible_if::COLLAPSIBLE_IF,
|
collapsible_if::COLLAPSIBLE_IF,
|
||||||
|
unicode::ZERO_WIDTH_SPACE,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
45
src/unicode.rs
Normal file
45
src/unicode.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use rustc::lint::*;
|
||||||
|
use syntax::ast::*;
|
||||||
|
use syntax::codemap::{BytePos, Span};
|
||||||
|
|
||||||
|
declare_lint!{ pub ZERO_WIDTH_SPACE, Deny, "Zero-width space is confusing" }
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Unicode;
|
||||||
|
|
||||||
|
impl LintPass for Unicode {
|
||||||
|
fn get_lints(&self) -> LintArray {
|
||||||
|
lint_array!(ZERO_WIDTH_SPACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||||
|
if let ExprLit(ref lit) = expr.node {
|
||||||
|
if let LitStr(ref string, _) = lit.node {
|
||||||
|
check_str(cx, string, lit.span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_str(cx: &Context, string: &str, span: Span) {
|
||||||
|
let mut start: Option<usize> = None;
|
||||||
|
for (i, c) in string.char_indices() {
|
||||||
|
if c == '\u{200B}' {
|
||||||
|
if start.is_none() { start = Some(i); }
|
||||||
|
} else {
|
||||||
|
lint_zero_width(cx, span, start);
|
||||||
|
start = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lint_zero_width(cx, span, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lint_zero_width(cx: &Context, span: Span, start: Option<usize>) {
|
||||||
|
start.map(|index| {
|
||||||
|
cx.span_lint(ZERO_WIDTH_SPACE, Span {
|
||||||
|
lo: span.lo + BytePos(index as u32),
|
||||||
|
hi: span.lo + BytePos(index as u32),
|
||||||
|
expn_id: span.expn_id,
|
||||||
|
}, "Zero-width space detected. Consider using \\u{200B}")
|
||||||
|
});
|
||||||
|
}
|
25
tests/compile-fail/unicode.rs
Normal file
25
tests/compile-fail/unicode.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(clippy)]
|
||||||
|
|
||||||
|
#[deny(zero_width_space)]
|
||||||
|
fn zero() {
|
||||||
|
print!("Here >< is a ZWS, and another");
|
||||||
|
//~^ ERROR Zero-width space detected. Consider using \u{200B}
|
||||||
|
//~^^ ERROR Zero-width space detected. Consider using \u{200B}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[deny(unicode_canon)]
|
||||||
|
fn canon() {
|
||||||
|
print!("̀ah?"); //not yet ~ERROR Non-canonical unicode sequence detected. Consider using à
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[deny(ascii_only)]
|
||||||
|
fn uni() {
|
||||||
|
println!("Üben!"); //not yet ~ERROR Unicode literal detected. Consider using \u{FC}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
zero();
|
||||||
|
uni();
|
||||||
|
canon();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue