]> git.lizzy.rs Git - rust.git/blob - src/unicode.rs
1854d5be7ff203060087913d2db2e0794b220824
[rust.git] / src / unicode.rs
1 use rustc::lint::*;
2 use syntax::ast::*;
3 use syntax::codemap::{BytePos, Span};
4 use utils::span_lint;
5
6 declare_lint!{ pub ZERO_WIDTH_SPACE, Deny, "Zero-width space is confusing" }
7
8 #[derive(Copy, Clone)]
9 pub struct Unicode;
10
11 impl LintPass for Unicode {
12     fn get_lints(&self) -> LintArray {
13         lint_array!(ZERO_WIDTH_SPACE)
14     }
15
16     fn check_expr(&mut self, cx: &Context, expr: &Expr) {
17         if let ExprLit(ref lit) = expr.node {
18             if let LitStr(ref string, _) = lit.node {
19                 check_str(cx, string, lit.span)
20             }
21         }
22     }
23 }
24
25 fn check_str(cx: &Context, string: &str, span: Span) {
26     let mut start: Option<usize> = None;
27     for (i, c) in string.char_indices() {
28         if c == '\u{200B}' {
29             if start.is_none() { start = Some(i); }
30         } else {
31             lint_zero_width(cx, span, start);
32             start = None;
33         }
34     }
35     lint_zero_width(cx, span, start);
36 }
37
38 fn lint_zero_width(cx: &Context, span: Span, start: Option<usize>) {
39     start.map(|index| {
40         span_lint(cx, ZERO_WIDTH_SPACE, Span {
41             lo: span.lo + BytePos(index as u32),
42             hi: span.lo + BytePos(index as u32),
43             expn_id: span.expn_id,
44         }, "Zero-width space detected. Consider using \\u{200B}")
45     });
46 }