2015-06-11 09:35:00 +00:00
|
|
|
use rustc::lint::*;
|
|
|
|
use syntax::ast::*;
|
|
|
|
use syntax::codemap::{BytePos, Span};
|
2015-08-16 06:54:43 +00:00
|
|
|
|
2015-07-26 14:53:11 +00:00
|
|
|
use utils::span_lint;
|
2015-06-11 09:35:00 +00:00
|
|
|
|
2015-08-13 08:32:35 +00:00
|
|
|
declare_lint!{ pub ZERO_WIDTH_SPACE, Deny,
|
|
|
|
"using a zero-width space in a string literal, which is confusing" }
|
|
|
|
declare_lint!{ pub NON_ASCII_LITERAL, Allow,
|
|
|
|
"using any literal non-ASCII chars in a string literal; suggests \
|
|
|
|
using the \\u escape instead" }
|
2015-06-11 09:35:00 +00:00
|
|
|
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct Unicode;
|
|
|
|
|
|
|
|
impl LintPass for Unicode {
|
2015-08-11 18:22:20 +00:00
|
|
|
fn get_lints(&self) -> LintArray {
|
2015-08-12 18:36:10 +00:00
|
|
|
lint_array!(ZERO_WIDTH_SPACE, NON_ASCII_LITERAL)
|
2015-06-11 09:35:00 +00:00
|
|
|
}
|
2015-08-11 18:22:20 +00:00
|
|
|
|
2015-06-11 09:35:00 +00:00
|
|
|
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
2015-08-11 18:22:20 +00:00
|
|
|
if let ExprLit(ref lit) = expr.node {
|
|
|
|
if let LitStr(ref string, _) = lit.node {
|
|
|
|
check_str(cx, string, lit.span)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-06-11 09:35:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn check_str(cx: &Context, string: &str, span: Span) {
|
2015-08-11 18:22:20 +00:00
|
|
|
for (i, c) in string.char_indices() {
|
|
|
|
if c == '\u{200B}' {
|
2015-08-12 18:36:10 +00:00
|
|
|
str_pos_lint(cx, ZERO_WIDTH_SPACE, span, i,
|
2015-08-13 06:15:42 +00:00
|
|
|
"zero-width space detected. Consider using `\\u{200B}`");
|
2015-08-12 18:36:10 +00:00
|
|
|
}
|
|
|
|
if c as u32 > 0x7F {
|
|
|
|
str_pos_lint(cx, NON_ASCII_LITERAL, span, i, &format!(
|
2015-08-13 06:15:42 +00:00
|
|
|
"literal non-ASCII character detected. Consider using `\\u{{{:X}}}`", c as u32));
|
2015-08-11 18:22:20 +00:00
|
|
|
}
|
|
|
|
}
|
2015-06-11 09:35:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-12 18:36:10 +00:00
|
|
|
fn str_pos_lint(cx: &Context, lint: &'static Lint, span: Span, index: usize, msg: &str) {
|
|
|
|
span_lint(cx, lint, Span { lo: span.lo + BytePos((1 + index) as u32),
|
|
|
|
hi: span.lo + BytePos((1 + index) as u32),
|
|
|
|
expn_id: span.expn_id }, msg);
|
|
|
|
|
2015-06-11 09:35:00 +00:00
|
|
|
}
|