mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter): add oxc/no-const-enum rule (#3435)
This commit is contained in:
parent
6a1f2c21df
commit
0d2c977c11
4 changed files with 103 additions and 0 deletions
|
|
@ -1288,6 +1288,13 @@ impl<'a> Modifiers<'a> {
|
|||
.map_or(false, |modifiers| modifiers.iter().any(|modifier| modifier.kind == target))
|
||||
}
|
||||
|
||||
pub fn find<F>(&self, f: F) -> Option<&Modifier>
|
||||
where
|
||||
F: Fn(&Modifier) -> bool,
|
||||
{
|
||||
self.0.as_ref().and_then(|modifiers| modifiers.iter().find(|modifier| f(modifier)))
|
||||
}
|
||||
|
||||
pub fn is_contains_declare(&self) -> bool {
|
||||
self.contains(ModifierKind::Declare)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ mod oxc {
|
|||
pub mod no_accumulating_spread;
|
||||
pub mod no_async_await;
|
||||
pub mod no_barrel_file;
|
||||
pub mod no_const_enum;
|
||||
pub mod number_arg_out_of_range;
|
||||
pub mod only_used_in_recursion;
|
||||
pub mod uninvoked_array_callback;
|
||||
|
|
@ -718,6 +719,7 @@ oxc_macros::declare_all_lint_rules! {
|
|||
oxc::missing_throw,
|
||||
oxc::no_accumulating_spread,
|
||||
oxc::no_barrel_file,
|
||||
oxc::no_const_enum,
|
||||
oxc::number_arg_out_of_range,
|
||||
oxc::only_used_in_recursion,
|
||||
oxc::no_async_await,
|
||||
|
|
|
|||
84
crates/oxc_linter/src/rules/oxc/no_const_enum.rs
Normal file
84
crates/oxc_linter/src/rules/oxc/no_const_enum.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
use oxc_ast::{ast::ModifierKind, AstKind};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::Span;
|
||||
|
||||
use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode};
|
||||
|
||||
fn no_const_enum_diagnostic(span0: Span) -> OxcDiagnostic {
|
||||
OxcDiagnostic::warn("oxc(no-const-enum): Unexpected const enum")
|
||||
.with_help("Const enums are not supported by bundlers and are incompatible with the isolatedModules mode. Their use can lead to import nonexistent values (because const enums are erased).")
|
||||
.with_labels([span0.into()])
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct NoConstEnum;
|
||||
|
||||
// Ported from <https://biomejs.dev/linter/rules/no-const-enum/>
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
///
|
||||
/// Disallow TypeScript `const enum`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// Const enums are enums that should be inlined at use sites.
|
||||
/// Const enums are not supported by bundlers and are incompatible with the isolatedModules mode.
|
||||
/// Their use can lead to import nonexistent values (because const enums are erased).
|
||||
///
|
||||
/// ### Example
|
||||
/// ```javascript
|
||||
/// const enum Color {
|
||||
/// Red,
|
||||
/// Green,
|
||||
/// Blue
|
||||
/// }
|
||||
/// ```
|
||||
NoConstEnum,
|
||||
restriction,
|
||||
);
|
||||
|
||||
impl Rule for NoConstEnum {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
if let AstKind::TSEnumDeclaration(enum_decl) = node.kind() {
|
||||
let Some(const_enum) =
|
||||
enum_decl.modifiers.find(|modifier| matches!(modifier.kind, ModifierKind::Const))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
ctx.diagnostic_with_fix(no_const_enum_diagnostic(const_enum.span), || {
|
||||
// const enum Color { Red, Green, Blue }
|
||||
// ^
|
||||
let start = const_enum.span.start;
|
||||
|
||||
// const enum Color { Red, Green, Blue }
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
let text = Span::new(start, enum_decl.span.end).source_text(ctx.source_text());
|
||||
|
||||
// const enum Color { Red, Green, Blue }
|
||||
// ^^^^^^
|
||||
let offset = u32::try_from(text.find("enum").unwrap_or(1)).unwrap_or(1); // 1 is the default offset
|
||||
|
||||
let end = start + offset;
|
||||
Fix::delete(Span::new(start, end))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec!["enum Color { Red, Green, Blue }"];
|
||||
|
||||
let fail = vec!["const enum Color { Red, Green, Blue }"];
|
||||
|
||||
let fix = vec![
|
||||
("const enum Color { Red, Green, Blue }", "enum Color { Red, Green, Blue }", None),
|
||||
("const enum Color { Red, Green, Blue }", "enum Color { Red, Green, Blue }", None),
|
||||
];
|
||||
|
||||
Tester::new(NoConstEnum::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
|
||||
}
|
||||
10
crates/oxc_linter/src/snapshots/no_const_enum.snap
Normal file
10
crates/oxc_linter/src/snapshots/no_const_enum.snap
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
expression: no_const_enum
|
||||
---
|
||||
⚠ oxc(no-const-enum): Unexpected const enum
|
||||
╭─[no_const_enum.tsx:1:1]
|
||||
1 │ const enum Color { Red, Green, Blue }
|
||||
· ─────
|
||||
╰────
|
||||
help: Const enums are not supported by bundlers and are incompatible with the isolatedModules mode. Their use can lead to import nonexistent values (because const enums are erased).
|
||||
Loading…
Reference in a new issue