Skip to content

Commit

Permalink
perf(linter): parse ts-directive manually
Browse files Browse the repository at this point in the history
  • Loading branch information
Devin-Yeung committed Sep 3, 2023
1 parent 37bf4c4 commit d3ae169
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions crates/oxc_linter/src/rules/typescript/ban_ts_comment.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use once_cell::sync::Lazy;
use oxc_diagnostics::{
miette::{self, Diagnostic},
thiserror::{self, Error},
Expand Down Expand Up @@ -126,13 +125,11 @@ impl Rule for BanTsComment {
fn run_once(&self, ctx: &LintContext) {
let comments = ctx.semantic().trivias().comments();
for (start, comment) in comments {
let regex = if comment.is_single_line() { &SINGLELINE } else { &MULTILINE };
let raw = &ctx.semantic().source_text()[*start as usize..comment.end() as usize];

if let Some(captures) = regex.captures(raw) {
if let Some(captures) = find_ts_comment_directive(raw, comment.is_single_line()) {
// safe to unwrap, if capture success, it can always capture one of the four directives
let directive = captures.name("directive").unwrap().as_str();
let description = captures.name("description").map_or("", |m| m.as_str().trim());
let (directive, description) = (captures.0, captures.1.trim());

match self.option(directive) {
DirectiveConfig::Boolean(on) => {
Expand Down Expand Up @@ -170,19 +167,6 @@ impl Rule for BanTsComment {
}
}

// regex to parse single line comment
static SINGLELINE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^/*\s*@ts-(?P<directive>expect-error|ignore|check|nocheck)(?P<description>.*)")
.unwrap()
});
// regex to parse multiline comment
static MULTILINE: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"^\s*(?:/|\*)*\s*@ts-(?P<directive>expect-error|ignore|check|nocheck)(?P<description>.*)",
)
.unwrap()
});

impl BanTsComment {
/// get the option for a given directive, caller should guarantee
/// the directive should be one of the ignore/check/nocheck/expect-error
Expand All @@ -197,6 +181,30 @@ impl BanTsComment {
}
}

pub fn find_ts_comment_directive(raw: &str, single_line: bool) -> Option<(&str, &str)> {
let prefix = "@ts-";
// For multi-line comments, get the last line
let mut lines = raw.lines();
let line = lines.next_back()?;
let index = line.find(prefix)?;
if !line[..index]
.chars()
.all(|c| c.is_whitespace() || if single_line { c == '/' } else { c == '*' || c == '/' })
{
return None;
}
let multi_len = lines.map(|line| line.len() + 1).sum::<usize>();
let start = index + prefix.len();
for directive in ["expect-error", "ignore", "nocheck", "check"] {
if line.get(start..start + directive.len()) == Some(directive) {
let start = multi_len + index + prefix.len();
let end = start + directive.len();
return Some((&raw[start..end], &raw[end..]));
}
}
None
}

#[test]
#[allow(clippy::too_many_lines)]
fn test() {
Expand Down

0 comments on commit d3ae169

Please sign in to comment.