mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(linter): typescript-eslint/prefer-enum-initializers (#3097)
This commit is contained in:
parent
51de41cc7a
commit
388ee5135a
3 changed files with 160 additions and 0 deletions
|
|
@ -138,6 +138,7 @@ mod typescript {
|
|||
pub mod no_unsafe_declaration_merging;
|
||||
pub mod no_var_requires;
|
||||
pub mod prefer_as_const;
|
||||
pub mod prefer_enum_initializers;
|
||||
pub mod prefer_for_of;
|
||||
pub mod prefer_function_type;
|
||||
pub mod prefer_ts_expect_error;
|
||||
|
|
@ -471,6 +472,7 @@ oxc_macros::declare_all_lint_rules! {
|
|||
typescript::array_type,
|
||||
typescript::ban_ts_comment,
|
||||
typescript::ban_tslint_comment,
|
||||
typescript::prefer_enum_initializers,
|
||||
typescript::ban_types,
|
||||
typescript::consistent_type_definitions,
|
||||
typescript::no_duplicate_enum_values,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
use oxc_ast::{ast::TSEnumMemberName, AstKind};
|
||||
use oxc_diagnostics::{
|
||||
miette::{self, Diagnostic},
|
||||
thiserror::Error,
|
||||
};
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::{CompactStr, Span};
|
||||
|
||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("typescript-eslint(prefer-enum-initializers):The value of the member {0:?} should be explicitly defined.")]
|
||||
#[diagnostic(severity(warning), help("Can be fixed to {0:?} = {1:?}."))]
|
||||
struct PreferEnumInitializersDiagnostic(CompactStr, usize, #[label] pub Span);
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct PreferEnumInitializers;
|
||||
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
/// Require each enum member value to be explicitly initialized.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// In projects where the value of `enum` members are important, allowing implicit values for enums can cause bugs if enums are modified over time.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```typescript
|
||||
/// // wrong, the value of `Close` is not constant
|
||||
/// enum Status {
|
||||
/// Open = 1,
|
||||
/// Close,
|
||||
/// }
|
||||
/// ```
|
||||
PreferEnumInitializers,
|
||||
pedantic
|
||||
);
|
||||
|
||||
impl Rule for PreferEnumInitializers {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
let AstKind::TSEnumDeclaration(decl) = node.kind() else { return };
|
||||
|
||||
for (index, member) in decl.members.iter().enumerate() {
|
||||
if member.initializer.is_none() {
|
||||
if let TSEnumMemberName::Identifier(i) = &member.id {
|
||||
ctx.diagnostic(PreferEnumInitializersDiagnostic(
|
||||
i.name.to_compact_str(),
|
||||
index + 1,
|
||||
member.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec![
|
||||
"
|
||||
enum Direction {}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up = 1,
|
||||
Down = 2,
|
||||
}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up = 'Up',
|
||||
Down = 'Down',
|
||||
}
|
||||
",
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
"
|
||||
enum Direction {
|
||||
Up,
|
||||
}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up = 'Up',
|
||||
Down,
|
||||
}
|
||||
",
|
||||
"
|
||||
enum Direction {
|
||||
Up,
|
||||
Down = 'Down',
|
||||
}
|
||||
",
|
||||
];
|
||||
|
||||
Tester::new(PreferEnumInitializers::NAME, pass, fail).test_and_snapshot();
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
expression: prefer_enum_initializers
|
||||
---
|
||||
⚠ typescript-eslint(prefer-enum-initializers):The value of the member "Up" should be explicitly defined.
|
||||
╭─[prefer_enum_initializers.tsx:3:6]
|
||||
2 │ enum Direction {
|
||||
3 │ Up,
|
||||
· ──
|
||||
4 │ }
|
||||
╰────
|
||||
help: Can be fixed to "Up" = 1.
|
||||
|
||||
⚠ typescript-eslint(prefer-enum-initializers):The value of the member "Up" should be explicitly defined.
|
||||
╭─[prefer_enum_initializers.tsx:3:6]
|
||||
2 │ enum Direction {
|
||||
3 │ Up,
|
||||
· ──
|
||||
4 │ Down,
|
||||
╰────
|
||||
help: Can be fixed to "Up" = 1.
|
||||
|
||||
⚠ typescript-eslint(prefer-enum-initializers):The value of the member "Down" should be explicitly defined.
|
||||
╭─[prefer_enum_initializers.tsx:4:6]
|
||||
3 │ Up,
|
||||
4 │ Down,
|
||||
· ────
|
||||
5 │ }
|
||||
╰────
|
||||
help: Can be fixed to "Down" = 2.
|
||||
|
||||
⚠ typescript-eslint(prefer-enum-initializers):The value of the member "Down" should be explicitly defined.
|
||||
╭─[prefer_enum_initializers.tsx:4:6]
|
||||
3 │ Up = 'Up',
|
||||
4 │ Down,
|
||||
· ────
|
||||
5 │ }
|
||||
╰────
|
||||
help: Can be fixed to "Down" = 2.
|
||||
|
||||
⚠ typescript-eslint(prefer-enum-initializers):The value of the member "Up" should be explicitly defined.
|
||||
╭─[prefer_enum_initializers.tsx:3:6]
|
||||
2 │ enum Direction {
|
||||
3 │ Up,
|
||||
· ──
|
||||
4 │ Down = 'Down',
|
||||
╰────
|
||||
help: Can be fixed to "Up" = 1.
|
||||
Loading…
Reference in a new issue