mirror of https://github.com/rust-lang/rust.git
fix #595
This commit is contained in:
parent
ceb9a8bdd7
commit
6525471214
|
@ -257,6 +257,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
ranges::RANGE_STEP_BY_ZERO,
|
ranges::RANGE_STEP_BY_ZERO,
|
||||||
ranges::RANGE_ZIP_WITH_LEN,
|
ranges::RANGE_ZIP_WITH_LEN,
|
||||||
regex::INVALID_REGEX,
|
regex::INVALID_REGEX,
|
||||||
|
regex::REGEX_MACRO,
|
||||||
regex::TRIVIAL_REGEX,
|
regex::TRIVIAL_REGEX,
|
||||||
returns::LET_AND_RETURN,
|
returns::LET_AND_RETURN,
|
||||||
returns::NEEDLESS_RETURN,
|
returns::NEEDLESS_RETURN,
|
||||||
|
|
44
src/regex.rs
44
src/regex.rs
|
@ -1,11 +1,11 @@
|
||||||
use regex_syntax;
|
use regex_syntax;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::collections::HashSet;
|
||||||
use syntax::ast::Lit_::LitStr;
|
use syntax::ast::Lit_::LitStr;
|
||||||
use syntax::ast::NodeId;
|
|
||||||
use syntax::codemap::{Span, BytePos};
|
use syntax::codemap::{Span, BytePos};
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
use rustc_front::hir::*;
|
use rustc_front::hir::*;
|
||||||
use rustc_front::intravisit::{Visitor, walk_block, FnKind};
|
use rustc_front::intravisit::{Visitor, walk_expr};
|
||||||
use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
|
use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
|
||||||
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
|
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
|
@ -48,7 +48,7 @@ declare_lint! {
|
||||||
/// **Example:** `regex!("foo|bar")`
|
/// **Example:** `regex!("foo|bar")`
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub REGEX_MACRO,
|
pub REGEX_MACRO,
|
||||||
Allow,
|
Warn,
|
||||||
"finds use of `regex!(_)`, suggests `Regex::new(_)` instead"
|
"finds use of `regex!(_)`, suggests `Regex::new(_)` instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,15 +62,9 @@ impl LintPass for RegexPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LateLintPass for RegexPass {
|
impl LateLintPass for RegexPass {
|
||||||
fn check_fn(&mut self,
|
fn check_crate(&mut self, cx: &LateContext, krate: &Crate) {
|
||||||
cx: &LateContext,
|
let mut visitor = RegexVisitor { cx: cx, spans: HashSet::new() };
|
||||||
_: FnKind,
|
krate.visit_all_items(&mut visitor);
|
||||||
_: &FnDecl,
|
|
||||||
block: &Block,
|
|
||||||
_: Span,
|
|
||||||
_: NodeId) {
|
|
||||||
let mut visitor = RegexVisitor { cx: cx, last: BytePos(0) };
|
|
||||||
visitor.visit_block(block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,25 +163,23 @@ fn is_trivial_regex(s: ®ex_syntax::Expr) -> Option<&'static str> {
|
||||||
|
|
||||||
struct RegexVisitor<'v, 't: 'v> {
|
struct RegexVisitor<'v, 't: 'v> {
|
||||||
cx: &'v LateContext<'v, 't>,
|
cx: &'v LateContext<'v, 't>,
|
||||||
last: BytePos
|
spans: HashSet<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'v, 't: 'v> Visitor<'v> for RegexVisitor<'v, 't> {
|
impl<'v, 't: 'v> Visitor<'v> for RegexVisitor<'v, 't> {
|
||||||
fn visit_block(&mut self, block: &'v Block) {
|
fn visit_expr(&mut self, expr: &'v Expr) {
|
||||||
if let Some(ref expr) = block.expr {
|
if let Some(span) = is_expn_of(self.cx, expr.span, "regex") {
|
||||||
if let Some(span) = is_expn_of(self.cx, expr.span, "regex") {
|
if self.spans.contains(&span) {
|
||||||
if span.lo == BytePos(0) || span.lo == self.last {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
span_lint(self.cx,
|
|
||||||
REGEX_MACRO,
|
|
||||||
span,
|
|
||||||
&format!("regex!(_): {:?}, {:?}", self.last, span.lo));
|
|
||||||
//"`regex!(_)` found. Use `Regex::new(_)`, which is faster for now.");
|
|
||||||
self.last = span.lo;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
span_lint(self.cx,
|
||||||
|
REGEX_MACRO,
|
||||||
|
span,
|
||||||
|
"`regex!(_)` found. \
|
||||||
|
Please use `Regex::new(_)`, which is faster for now.");
|
||||||
|
self.spans.insert(span);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
walk_block(self, block);
|
walk_expr(self, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[deny(mut_mut)]
|
#[deny(mut_mut)]
|
||||||
|
#[allow(regex_macro)]
|
||||||
fn test_regex() {
|
fn test_regex() {
|
||||||
let pattern = regex!(r"^(?P<level>[#]+)\s(?P<title>.+)$");
|
let pattern = regex!(r"^(?P<level>[#]+)\s(?P<title>.+)$");
|
||||||
assert!(pattern.is_match("# headline"));
|
assert!(pattern.is_match("# headline"));
|
||||||
|
|
Loading…
Reference in New Issue