Skip to content

Commit

Permalink
feat(linter): eslint-plugin-unicorn(filename-case) (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen authored Oct 11, 2023
1 parent d5fb3d4 commit eaa0c58
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 10 additions & 9 deletions crates/oxc_linter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ oxc_syntax = { workspace = true }
oxc_formatter = { workspace = true }
oxc_resolver = { workspace = true }

rayon = { workspace = true }
lazy_static = { workspace = true } # used in oxc_macros
serde_json = { workspace = true }
regex = { workspace = true }
rustc-hash = { workspace = true }
phf = { workspace = true, features = ["macros"] }
num-traits = { workspace = true }
itertools = { workspace = true }
dashmap = { workspace = true }
rayon = { workspace = true }
lazy_static = { workspace = true } # used in oxc_macros
serde_json = { workspace = true }
regex = { workspace = true }
rustc-hash = { workspace = true }
phf = { workspace = true, features = ["macros"] }
num-traits = { workspace = true }
itertools = { workspace = true }
dashmap = { workspace = true }
convert_case = { workspace = true }

rust-lapper = "1.1.0"
once_cell = "1.18.0"
Expand Down
11 changes: 9 additions & 2 deletions crates/oxc_linter/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, path::Path, rc::Rc};

use oxc_diagnostics::Error;
use oxc_formatter::{Formatter, FormatterOptions};
Expand All @@ -22,10 +22,12 @@ pub struct LintContext<'a> {
fix: bool,

current_rule_name: &'static str,

file_path: Box<Path>,
}

impl<'a> LintContext<'a> {
pub fn new(semantic: &Rc<Semantic<'a>>) -> Self {
pub fn new(file_path: Box<Path>, semantic: &Rc<Semantic<'a>>) -> Self {
let disable_directives =
DisableDirectivesBuilder::new(semantic.source_text(), semantic.trivias()).build();
Self {
Expand All @@ -34,6 +36,7 @@ impl<'a> LintContext<'a> {
disable_directives,
fix: false,
current_rule_name: "",
file_path,
}
}

Expand All @@ -55,6 +58,10 @@ impl<'a> LintContext<'a> {
self.semantic().source_type()
}

pub fn file_path(&self) -> &Path {
&self.file_path
}

pub fn with_rule_name(&mut self, name: &'static str) {
self.current_rule_name = name;
}
Expand Down
2 changes: 2 additions & 0 deletions crates/oxc_linter/src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ mod jest {
}

mod unicorn {
pub mod filename_case;
pub mod no_instanceof_array;
pub mod no_thenable;
pub mod no_unnecessary_await;
Expand Down Expand Up @@ -231,6 +232,7 @@ oxc_macros::declare_all_lint_rules! {
unicorn::no_instanceof_array,
unicorn::no_unnecessary_await,
unicorn::no_thenable,
unicorn::filename_case,
import::named,
import::no_cycle,
import::no_self_import,
Expand Down
74 changes: 74 additions & 0 deletions crates/oxc_linter/src/rules/unicorn/filename_case.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use convert_case::{Case, Casing};
use oxc_diagnostics::{
miette::{self, Diagnostic},
thiserror::{self, Error},
};
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{context::LintContext, rule::Rule};

#[derive(Debug, Error, Diagnostic)]
#[error("eslint-plugin-unicorn(filename-case): Filename should not be in {1} case")]
#[diagnostic(severity(warning))]
struct FilenameCaseDiagnostic(#[label] pub Span, &'static str);

#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone)]
pub struct FilenameCase {
kebab_case: bool,
camel_case: bool,
snake_case: bool,
pascal_case: bool,
underscore_case: bool,
}

impl Default for FilenameCase {
fn default() -> Self {
Self {
kebab_case: false,
camel_case: true,
snake_case: false,
pascal_case: true,
underscore_case: false,
}
}
}

declare_oxc_lint!(
/// ### What it does
///
/// ### Why is this bad?
///
/// ### Example
/// ```
FilenameCase,
style
);

impl Rule for FilenameCase {
fn run_once<'a>(&self, ctx: &LintContext<'_>) {
let Some(filename) = ctx.file_path().file_stem().and_then(|s| s.to_str()) else { return };

let mut case_name = "";

let cases = [
(Case::Kebab, "kebab", self.kebab_case),
(Case::Camel, "camel", self.camel_case),
(Case::Snake, "snake", self.snake_case),
(Case::Pascal, "pascal", self.pascal_case),
(Case::Pascal, "underscore", self.underscore_case),
];

for (case, name, condition) in cases {
if filename.to_case(case) == filename {
if condition {
return;
}
case_name = name;
}
}

ctx.diagnostic(FilenameCaseDiagnostic(Span::default(), case_name));
}
}
3 changes: 2 additions & 1 deletion crates/oxc_linter/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ impl Runtime {
return semantic_ret.errors.into_iter().map(|err| Message::new(err, None)).collect();
};

let lint_ctx = LintContext::new(&Rc::new(semantic_ret.semantic));
let lint_ctx =
LintContext::new(path.to_path_buf().into_boxed_path(), &Rc::new(semantic_ret.semantic));
self.linter.run(lint_ctx)
}

Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_linter_plugin/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ fn run_individual_test(

let semantic = Rc::new(semantic);

let mut lint_ctx = LintContext::new(&Rc::clone(&semantic));
let mut lint_ctx =
LintContext::new(PathBuf::from(file_path).into_boxed_path(), &Rc::clone(&semantic));

let result = plugin.lint_file_with_rule(
&mut lint_ctx,
Expand Down
7 changes: 4 additions & 3 deletions crates/oxc_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod options;

use std::{cell::RefCell, collections::BTreeMap, rc::Rc, sync::Arc};
use std::{cell::RefCell, collections::BTreeMap, path::PathBuf, rc::Rc, sync::Arc};

use oxc_allocator::Allocator;
use oxc_diagnostics::Error;
Expand Down Expand Up @@ -159,7 +159,8 @@ impl Oxc {

let allocator = Allocator::default();
let source_text = &self.source_text;
let source_type = SourceType::from_path("test.tsx").unwrap_or_default();
let path = PathBuf::from("test.tsx");
let source_type = SourceType::from_path(&path).unwrap_or_default();

let ret = Parser::new(&allocator, source_text, source_type)
.allow_return_outside_function(parser_options.allow_return_outside_function)
Expand All @@ -184,7 +185,7 @@ impl Oxc {
self.save_diagnostics(semantic_ret.errors);

let semantic = Rc::new(semantic_ret.semantic);
let lint_ctx = LintContext::new(&semantic);
let lint_ctx = LintContext::new(path.into_boxed_path(), &semantic);
let linter_ret = Linter::new().run(lint_ctx);
let diagnostics = linter_ret.into_iter().map(|e| e.error).collect();
self.save_diagnostics(diagnostics);
Expand Down
3 changes: 2 additions & 1 deletion editor/vscode/server/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ impl IsolatedLintHandler {
return Some(Self::wrap_diagnostics(path, &source_text, reports));
};

let mut lint_ctx = LintContext::new(&Rc::new(semantic_ret.semantic));
let mut lint_ctx =
LintContext::new(path.to_path_buf().into_boxed_path(), &Rc::new(semantic_ret.semantic));
{
if let Ok(guard) = plugin.read() {
if let Some(plugin) = &*guard {
Expand Down
4 changes: 3 additions & 1 deletion tasks/benchmark/benches/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ fn bench_linter(criterion: &mut Criterion) {
LintOptions::default().with_filter(vec![(AllowWarnDeny::Deny, "all".into())]);
let linter = Linter::from_options(lint_options);
let semantic = Rc::new(semantic_ret.semantic);
b.iter(|| linter.run(LintContext::new(&semantic)));
b.iter(|| {
linter.run(LintContext::new(PathBuf::from("").into_boxed_path(), &semantic))
});
},
);
}
Expand Down

0 comments on commit eaa0c58

Please sign in to comment.