diff --git a/Cargo.lock b/Cargo.lock index e5f716c768390..40a79ef7d191e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,12 +252,6 @@ dependencies = [ "half", ] -[[package]] -name = "clean-path" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa6b4b263a5d737e9bf6b7c09b72c41a5480aec4d7219af827f6564e950b6a5" - [[package]] name = "codspeed" version = "2.6.0" @@ -1283,13 +1277,13 @@ dependencies = [ [[package]] name = "oxc-browserslist" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3185bccb8ad893e683b7a907d297d294efa096f8b199e9ad8be82c8fd05ff5c" +checksum = "0d67676f247b63c0f6a8ed20f6c1faa39ff5e0e4af923284a0857623eec5ab14" dependencies = [ "js-sys", "nom", - "rustc-hash 1.1.0", + "rustc-hash", "serde", "serde-wasm-bindgen", "serde_json", @@ -1325,6 +1319,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "oxc_ast_codegen" +version = "0.0.0" +dependencies = [ + "itertools 0.13.0", + "lazy_static", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "serde", + "syn", +] + [[package]] name = "oxc_ast_macros" version = "0.15.0" @@ -1357,7 +1365,7 @@ dependencies = [ "itertools 0.13.0", "oxc_syntax", "petgraph", - "rustc-hash 2.0.0", + "rustc-hash", ] [[package]] @@ -1374,7 +1382,7 @@ dependencies = [ "oxc_sourcemap", "oxc_span", "oxc_syntax", - "rustc-hash 2.0.0", + "rustc-hash", ] [[package]] @@ -1441,7 +1449,7 @@ dependencies = [ "oxc_parser", "oxc_span", "oxc_syntax", - "rustc-hash 2.0.0", + "rustc-hash", ] [[package]] @@ -1505,7 +1513,7 @@ dependencies = [ "rayon", "regex", "rust-lapper", - "rustc-hash 2.0.0", + "rustc-hash", "schemars", "serde", "serde_json", @@ -1584,7 +1592,7 @@ dependencies = [ "oxc_diagnostics", "oxc_span", "oxc_syntax", - "rustc-hash 2.0.0", + "rustc-hash", "seq-macro", "serde_json", "static_assertions", @@ -1647,20 +1655,20 @@ dependencies = [ [[package]] name = "oxc_resolver" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd177c1f521d3c6631fa96abb6d97220ce4bed102e1e0172b11496ed9442fae" +checksum = "5b9acc6904f2556785bcd5f436d854fb5cb9f66289e26ba9179a02ea3732a6f4" dependencies = [ "dashmap", "dunce", + "indexmap", "json-strip-comments", "once_cell", - "rustc-hash 1.1.0", + "rustc-hash", "serde", "serde_json", "thiserror", "tracing", - "typescript_tsconfig_json", ] [[package]] @@ -1679,7 +1687,7 @@ dependencies = [ "oxc_span", "oxc_syntax", "phf", - "rustc-hash 2.0.0", + "rustc-hash", "serde", "tsify", "wasm-bindgen", @@ -1692,7 +1700,7 @@ dependencies = [ "base64-simd", "cfg-if", "rayon", - "rustc-hash 2.0.0", + "rustc-hash", "serde", "serde_json", ] @@ -1717,7 +1725,7 @@ dependencies = [ "oxc_index", "oxc_span", "phf", - "rustc-hash 2.0.0", + "rustc-hash", "ryu-js", "serde", "tsify", @@ -1782,7 +1790,7 @@ dependencies = [ "oxc_syntax", "oxc_traverse", "ropey", - "rustc-hash 2.0.0", + "rustc-hash", "serde", "serde_json", ] @@ -2002,6 +2010,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -2169,12 +2187,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.0.0" @@ -2854,19 +2866,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "typescript_tsconfig_json" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7cc416eaf05297012ead9d192226fe9a92e9a20f64f8780efb9085aaae9b590" -dependencies = [ - "clean-path", - "indexmap", - "rustc-hash 1.1.0", - "serde", - "serde_json", -] - [[package]] name = "ucd-trie" version = "0.1.6" diff --git a/Cargo.toml b/Cargo.toml index 37bf1db076795..23c368ed1602d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,7 @@ oxc_macros = { path = "crates/oxc_macros" } oxc_linter = { path = "crates/oxc_linter" } oxc_prettier = { path = "crates/oxc_prettier" } oxc_tasks_common = { path = "tasks/common" } +oxc_ast_codegen = { path = "tasks/oxc_ast_codegen" } napi = "2.16.6" napi-derive = "2.16.5" @@ -142,7 +143,7 @@ tower-lsp = "0.20.0" trybuild = "1.0.96" unicode-id-start = "1.*" # Relaxed version so the user can decide which unicode version to use. ureq = { version = "2.9.6", default-features = false } -url = "=2.5.2" +url = "2.5.2" walkdir = "2.5.0" indexmap = "2.2.6" static_assertions = "1.1.0" @@ -168,7 +169,7 @@ memchr = "2.7.2" once_cell = "1.19.0" ouroboros = "0.18.4" owo-colors = "4.0.0" -oxc_resolver = "1.8.1" +oxc_resolver = "1.8.2" petgraph = "0.6.5" rust-lapper = "1.1.0" similar = "2.5.0" @@ -178,12 +179,13 @@ saphyr = "0.0.1" base64-simd = "0.8" cfg-if = "1.0.0" schemars = "0.8.21" -oxc-browserslist = "1.0.0" +oxc-browserslist = "1.0.1" +prettyplease = "0.2.20" criterion2 = { version = "0.11.0", default-features = false } daachorse = { version = "1.0.0" } [workspace.metadata.cargo-shear] -ignored = ["napi", "oxc_traverse"] +ignored = ["napi", "oxc_traverse", "oxc_ast_codegen", "prettyplease"] [profile.dev] # Disabling debug info speeds up local and CI builds, diff --git a/apps/oxlint/fixtures/eslintrc_vitest_replace/eslintrc.json b/apps/oxlint/fixtures/eslintrc_vitest_replace/eslintrc.json new file mode 100644 index 0000000000000..9db9a461312ee --- /dev/null +++ b/apps/oxlint/fixtures/eslintrc_vitest_replace/eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "vitest/no-disabled-tests": "error" + } +} diff --git a/apps/oxlint/fixtures/eslintrc_vitest_replace/foo.js b/apps/oxlint/fixtures/eslintrc_vitest_replace/foo.js new file mode 100644 index 0000000000000..6f0f89fd0b220 --- /dev/null +++ b/apps/oxlint/fixtures/eslintrc_vitest_replace/foo.js @@ -0,0 +1,3 @@ +test.skip('foo', () => { + // ... +}) diff --git a/apps/oxlint/src/command/lint.rs b/apps/oxlint/src/command/lint.rs index 8b3c7a88b6a06..de29b4720481a 100644 --- a/apps/oxlint/src/command/lint.rs +++ b/apps/oxlint/src/command/lint.rs @@ -208,6 +208,10 @@ pub struct EnablePlugins { #[bpaf(switch, hide_usage)] pub jest_plugin: bool, + /// Enable the Vitest plugin and detect test problems + #[bpaf(switch, hide_usage)] + pub vitest_plugin: bool, + /// Enable the JSX-a11y plugin and detect accessibility problems #[bpaf(switch, hide_usage)] pub jsx_a11y_plugin: bool, diff --git a/apps/oxlint/src/lint/mod.rs b/apps/oxlint/src/lint/mod.rs index 3288eb8edef7b..777fdfee31d8b 100644 --- a/apps/oxlint/src/lint/mod.rs +++ b/apps/oxlint/src/lint/mod.rs @@ -101,6 +101,7 @@ impl Runner for LintRunner { .with_import_plugin(enable_plugins.import_plugin) .with_jsdoc_plugin(enable_plugins.jsdoc_plugin) .with_jest_plugin(enable_plugins.jest_plugin) + .with_vitest_plugin(enable_plugins.vitest_plugin) .with_jsx_a11y_plugin(enable_plugins.jsx_a11y_plugin) .with_nextjs_plugin(enable_plugins.nextjs_plugin) .with_react_perf_plugin(enable_plugins.react_perf_plugin); @@ -112,7 +113,7 @@ impl Runner for LintRunner { let mut err = String::new(); handler.render_report(&mut err, diagnostic.as_ref()).unwrap(); return CliRunResult::InvalidOptions { - message: "Failed to parse configuration file.\n{err}".to_string(), + message: format!("Failed to parse configuration file.\n{err}"), }; } }; @@ -488,4 +489,26 @@ mod test { assert!(test_invalid_options(&["--tsconfig", "oxc/tsconfig.json"]) .contains("oxc/tsconfig.json\" does not exist, Please provide a valid tsconfig file.")); } + + #[test] + fn test_enable_vitest_plugin() { + let args = &[ + "-c", + "fixtures/eslintrc_vitest_replace/eslintrc.json", + "fixtures/eslintrc_vitest_replace/foo.js", + ]; + let result = test(args); + assert_eq!(result.number_of_files, 1); + assert_eq!(result.number_of_errors, 0); + + let args = &[ + "--vitest-plugin", + "-c", + "fixtures/eslintrc_vitest_replace/eslintrc.json", + "fixtures/eslintrc_vitest_replace/foo.js", + ]; + let result = test(args); + assert_eq!(result.number_of_files, 1); + assert_eq!(result.number_of_errors, 1); + } } diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 775fdb5f63abf..f16729a645bee 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -25,7 +25,7 @@ use tsify::Tsify; #[visited_node( scope(ScopeFlags::Top), - strict_if(self.source_type.is_strict() || self.directives.iter().any(Directive::is_use_strict)) + strict_if(self.source_type.is_strict() || self.directives.iter().any(Directive::is_use_strict)), )] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -55,7 +55,7 @@ pub enum Expression<'a> { BooleanLiteral(Box<'a, BooleanLiteral>) = 0, NullLiteral(Box<'a, NullLiteral>) = 1, NumericLiteral(Box<'a, NumericLiteral<'a>>) = 2, - BigintLiteral(Box<'a, BigIntLiteral<'a>>) = 3, + BigIntLiteral(Box<'a, BigIntLiteral<'a>>) = 3, RegExpLiteral(Box<'a, RegExpLiteral<'a>>) = 4, StringLiteral(Box<'a, StringLiteral<'a>>) = 5, TemplateLiteral(Box<'a, TemplateLiteral<'a>>) = 6, @@ -110,7 +110,7 @@ macro_rules! match_expression { $ty::BooleanLiteral(_) | $ty::NullLiteral(_) | $ty::NumericLiteral(_) - | $ty::BigintLiteral(_) + | $ty::BigIntLiteral(_) | $ty::RegExpLiteral(_) | $ty::StringLiteral(_) | $ty::TemplateLiteral(_) @@ -1101,7 +1101,7 @@ pub struct WhileStatement<'a> { /// For Statement #[visited_node( scope(ScopeFlags::empty()), - scope_if(self.init.as_ref().is_some_and(ForStatementInit::is_lexical_declaration)) + scope_if(self.init.as_ref().is_some_and(ForStatementInit::is_lexical_declaration)), )] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1228,7 +1228,7 @@ pub struct WithStatement<'a> { } /// Switch Statement -#[visited_node(scope(ScopeFlags::empty()), enter_scope_before(cases))] +#[visited_node(scope(ScopeFlags::empty()))] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1236,6 +1236,7 @@ pub struct SwitchStatement<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub discriminant: Expression<'a>, + #[scope(enter_before)] pub cases: Vec<'a, SwitchCase<'a>>, pub scope_id: Cell>, } @@ -1326,8 +1327,6 @@ pub struct DebuggerStatement { #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct BindingPattern<'a> { - #[cfg_attr(feature = "serialize", serde(skip))] - pub span: Span, // serde(flatten) the attributes because estree has no `BindingPattern` #[cfg_attr(feature = "serialize", serde(flatten))] #[cfg_attr( @@ -1426,7 +1425,7 @@ pub struct BindingRestElement<'a> { #[visited_node( // TODO: `ScopeFlags::Function` is not correct if this is a `MethodDefinition` scope(ScopeFlags::Function), - strict_if(self.body.as_ref().is_some_and(|body| body.has_use_strict_directive())) + strict_if(self.body.as_ref().is_some_and(|body| body.has_use_strict_directive())), )] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1533,7 +1532,7 @@ pub struct FunctionBody<'a> { /// Arrow Function Definitions #[visited_node( scope(ScopeFlags::Function | ScopeFlags::Arrow), - strict_if(self.body.has_use_strict_directive()) + strict_if(self.body.has_use_strict_directive()), )] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1566,7 +1565,7 @@ pub struct YieldExpression<'a> { } /// Class Definitions -#[visited_node(scope(ScopeFlags::StrictMode), enter_scope_before(id))] +#[visited_node(scope(ScopeFlags::StrictMode))] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] @@ -1575,6 +1574,7 @@ pub struct Class<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub decorators: Vec<'a, Decorator<'a>>, + #[scope(enter_before)] pub id: Option>, pub super_class: Option>, pub body: Box<'a, ClassBody<'a>>, diff --git a/crates/oxc_ast/src/ast/macros.rs b/crates/oxc_ast/src/ast/macros.rs index 2c1e5179d7d05..698b1a2dbdd1e 100644 --- a/crates/oxc_ast/src/ast/macros.rs +++ b/crates/oxc_ast/src/ast/macros.rs @@ -93,7 +93,7 @@ macro_rules! inherit_variants { /// Inherited from [`Expression`] NumericLiteral(Box<'a, NumericLiteral<'a>>) = 2, /// Inherited from [`Expression`] - BigintLiteral(Box<'a, BigIntLiteral<'a>>) = 3, + BigIntLiteral(Box<'a, BigIntLiteral<'a>>) = 3, /// Inherited from [`Expression`] RegExpLiteral(Box<'a, RegExpLiteral<'a>>) = 4, /// Inherited from [`Expression`] @@ -189,7 +189,7 @@ macro_rules! inherit_variants { BooleanLiteral, NullLiteral, NumericLiteral, - BigintLiteral, + BigIntLiteral, RegExpLiteral, StringLiteral, TemplateLiteral, diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index d5e922c307c07..9a616e29b6cca 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -46,7 +46,7 @@ pub struct TSThisParameter<'a> { /// Enum Declaration /// /// `const_opt` enum `BindingIdentifier` { `EnumBody_opt` } -#[visited_node(scope(ScopeFlags::empty()), enter_scope_before(members))] +#[visited_node(scope(ScopeFlags::empty()))] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -54,6 +54,7 @@ pub struct TSEnumDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub id: BindingIdentifier<'a>, + #[scope(enter_before)] pub members: Vec<'a, TSEnumMember<'a>>, pub r#const: bool, pub declare: bool, @@ -121,7 +122,7 @@ pub enum TSLiteral<'a> { BooleanLiteral(Box<'a, BooleanLiteral>), NullLiteral(Box<'a, NullLiteral>), NumericLiteral(Box<'a, NumericLiteral<'a>>), - BigintLiteral(Box<'a, BigIntLiteral<'a>>), + BigIntLiteral(Box<'a, BigIntLiteral<'a>>), RegExpLiteral(Box<'a, RegExpLiteral<'a>>), StringLiteral(Box<'a, StringLiteral<'a>>), TemplateLiteral(Box<'a, TemplateLiteral<'a>>), @@ -784,8 +785,7 @@ pub enum TSTypePredicateName<'a> { #[visited_node( scope(ScopeFlags::TsModuleBlock), - enter_scope_before(body), - strict_if(self.body.as_ref().is_some_and(|body| body.is_strict())) + strict_if(self.body.as_ref().is_some_and(|body| body.is_strict())), )] #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -794,6 +794,7 @@ pub struct TSModuleDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub id: TSModuleDeclarationName<'a>, + #[scope(enter_before)] pub body: Option>, /// The keyword used to define this module declaration /// ```text diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index 8c8edb2ecc9f9..10c01a5a68053 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -68,11 +68,13 @@ impl<'a> AstBuilder<'a> { Atom::from(String::from_str_in(value, self.allocator).into_bump_str()) } + /// # SAFETY + /// This method is completely unsound and should not be used. + /// We need to remove all uses of it. Please don't add any more! + /// #[inline] pub fn copy(self, src: &T) -> T { - // SAFETY: - // This should be safe as long as `src` is an reference from the allocator. - // But honestly, I'm not really sure if this is safe. + // SAFETY: Not safe (see above) #[allow(unsafe_code)] unsafe { std::mem::transmute_copy(src) @@ -233,7 +235,7 @@ impl<'a> AstBuilder<'a> { #[inline] pub fn literal_bigint_expression(self, literal: BigIntLiteral<'a>) -> Expression<'a> { - Expression::BigintLiteral(self.alloc(literal)) + Expression::BigIntLiteral(self.alloc(literal)) } #[inline] @@ -1189,12 +1191,11 @@ impl<'a> AstBuilder<'a> { #[inline] pub fn binding_pattern( self, - span: Span, kind: BindingPatternKind<'a>, type_annotation: Option>>, optional: bool, ) -> BindingPattern<'a> { - BindingPattern { span, kind, type_annotation, optional } + BindingPattern { kind, type_annotation, optional } } #[inline] @@ -1255,7 +1256,6 @@ impl<'a> AstBuilder<'a> { ) -> BindingPattern<'a> { let pattern = self.alloc(AssignmentPattern { span, left, right }); BindingPattern { - span, kind: BindingPatternKind::AssignmentPattern(pattern), type_annotation: None, optional: false, diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index ac1400f2a8bb5..745008f665e89 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -94,7 +94,7 @@ impl<'a> Expression<'a> { Self::BooleanLiteral(_) | Self::NullLiteral(_) | Self::NumericLiteral(_) - | Self::BigintLiteral(_) + | Self::BigIntLiteral(_) | Self::RegExpLiteral(_) | Self::StringLiteral(_) ) @@ -246,7 +246,7 @@ impl<'a> Expression<'a> { Self::BooleanLiteral(lit) => Some(lit.value), Self::NullLiteral(_) => Some(false), Self::NumericLiteral(lit) => Some(lit.value != 0.0), - Self::BigintLiteral(lit) => Some(!lit.is_zero()), + Self::BigIntLiteral(lit) => Some(!lit.is_zero()), Self::RegExpLiteral(_) => Some(true), Self::StringLiteral(lit) => Some(!lit.value.is_empty()), _ => None, @@ -265,7 +265,7 @@ impl<'a> Expression<'a> { Self::BooleanLiteral(_) | Self::NullLiteral(_) | Self::NumericLiteral(_) - | Self::BigintLiteral(_) + | Self::BigIntLiteral(_) | Self::RegExpLiteral(_) | Self::StringLiteral(_) => true, Self::TemplateLiteral(lit) if lit.is_no_substitution_template() => true, @@ -337,7 +337,7 @@ impl<'a> PropertyKey<'a> { Self::StringLiteral(lit) => Some(lit.value.to_compact_str()), Self::RegExpLiteral(lit) => Some(lit.regex.to_string().into()), Self::NumericLiteral(lit) => Some(lit.value.to_string().into()), - Self::BigintLiteral(lit) => Some(lit.raw.to_compact_str()), + Self::BigIntLiteral(lit) => Some(lit.raw.to_compact_str()), Self::NullLiteral(_) => Some("null".into()), Self::TemplateLiteral(lit) => lit .expressions @@ -872,8 +872,8 @@ impl<'a> Hash for CatchClause<'a> { } impl<'a> BindingPattern<'a> { - pub fn new_with_kind(span: Span, kind: BindingPatternKind<'a>) -> Self { - Self { span, kind, type_annotation: None, optional: false } + pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self { + Self { kind, type_annotation: None, optional: false } } pub fn get_identifier(&self) -> Option> { diff --git a/crates/oxc_ast/src/ast_impl/ts.rs b/crates/oxc_ast/src/ast_impl/ts.rs index 749ab3325d654..8ec765af10c3d 100644 --- a/crates/oxc_ast/src/ast_impl/ts.rs +++ b/crates/oxc_ast/src/ast_impl/ts.rs @@ -9,7 +9,7 @@ use std::{cell::Cell, hash::Hash}; use oxc_allocator::Vec; -use oxc_span::{Atom, GetSpan, Span}; +use oxc_span::{Atom, Span}; use crate::ast::*; @@ -103,15 +103,6 @@ impl<'a> TSTypeName<'a> { } } -impl GetSpan for TSTypeName<'_> { - fn span(&self) -> Span { - match self { - TSTypeName::IdentifierReference(ident) => ident.span, - TSTypeName::QualifiedName(name) => name.span, - } - } -} - impl<'a> TSTypeParameter<'a> { pub fn new( span: Span, diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind_impl.rs similarity index 52% rename from crates/oxc_ast/src/ast_kind.rs rename to crates/oxc_ast/src/ast_kind_impl.rs index b9cb6349bd45d..c02deb6f1bcd3 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind_impl.rs @@ -1,224 +1,6 @@ -use oxc_span::{Atom, GetSpan, Span}; +use oxc_span::Atom; -#[allow(clippy::wildcard_imports)] -use crate::ast::*; - -macro_rules! ast_kinds { - { $($ident:ident($type:ty),)* } => ( - #[derive(Debug, Clone, Copy)] - pub enum AstType { - $($ident,)* - } - - /// Untyped AST Node Kind - #[derive(Debug, Clone, Copy)] - pub enum AstKind<'a> { - $($ident($type),)* - } - ) -} - -ast_kinds! { - Program(&'a Program<'a>), - Directive(&'a Directive<'a>), - Hashbang(&'a Hashbang<'a>), - - BlockStatement(&'a BlockStatement<'a>), - BreakStatement(&'a BreakStatement<'a>), - ContinueStatement(&'a ContinueStatement<'a>), - DebuggerStatement(&'a DebuggerStatement), - DoWhileStatement(&'a DoWhileStatement<'a>), - EmptyStatement(&'a EmptyStatement), - ExpressionStatement(&'a ExpressionStatement<'a>), - ForInStatement(&'a ForInStatement<'a>), - ForOfStatement(&'a ForOfStatement<'a>), - ForStatement(&'a ForStatement<'a>), - ForStatementInit(&'a ForStatementInit<'a>), - IfStatement(&'a IfStatement<'a>), - LabeledStatement(&'a LabeledStatement<'a>), - ReturnStatement(&'a ReturnStatement<'a>), - SwitchStatement(&'a SwitchStatement<'a>), - ThrowStatement(&'a ThrowStatement<'a>), - TryStatement(&'a TryStatement<'a>), - WhileStatement(&'a WhileStatement<'a>), - WithStatement(&'a WithStatement<'a>), - - SwitchCase(&'a SwitchCase<'a>), - CatchClause(&'a CatchClause<'a>), - FinallyClause(&'a BlockStatement<'a>), - - VariableDeclaration(&'a VariableDeclaration<'a>), - VariableDeclarator(&'a VariableDeclarator<'a>), - - UsingDeclaration(&'a UsingDeclaration<'a>), - - IdentifierName(&'a IdentifierName<'a>), - IdentifierReference(&'a IdentifierReference<'a>), - BindingIdentifier(&'a BindingIdentifier<'a>), - LabelIdentifier(&'a LabelIdentifier<'a>), - PrivateIdentifier(&'a PrivateIdentifier<'a>), - - NumericLiteral(&'a NumericLiteral<'a>), - StringLiteral(&'a StringLiteral<'a>), - BooleanLiteral(&'a BooleanLiteral), - NullLiteral(&'a NullLiteral), - BigintLiteral(&'a BigIntLiteral<'a>), - RegExpLiteral(&'a RegExpLiteral<'a>), - TemplateLiteral(&'a TemplateLiteral<'a>), - - MetaProperty(&'a MetaProperty<'a>), - Super(&'a Super), - - ArrayExpression(&'a ArrayExpression<'a>), - ArrowFunctionExpression(&'a ArrowFunctionExpression<'a>), - AssignmentExpression(&'a AssignmentExpression<'a>), - AwaitExpression(&'a AwaitExpression<'a>), - BinaryExpression(&'a BinaryExpression<'a>), - CallExpression(&'a CallExpression<'a>), - ChainExpression(&'a ChainExpression<'a>), - ConditionalExpression(&'a ConditionalExpression<'a>), - LogicalExpression(&'a LogicalExpression<'a>), - MemberExpression(&'a MemberExpression<'a>), - NewExpression(&'a NewExpression<'a>), - ObjectExpression(&'a ObjectExpression<'a>), - ParenthesizedExpression(&'a ParenthesizedExpression<'a>), - SequenceExpression(&'a SequenceExpression<'a>), - TaggedTemplateExpression(&'a TaggedTemplateExpression<'a>), - ThisExpression(&'a ThisExpression), - UnaryExpression(&'a UnaryExpression<'a>), - UpdateExpression(&'a UpdateExpression<'a>), - YieldExpression(&'a YieldExpression<'a>), - ImportExpression(&'a ImportExpression<'a>), - PrivateInExpression(&'a PrivateInExpression<'a>), - - ObjectProperty(&'a ObjectProperty<'a>), - PropertyKey(&'a PropertyKey<'a>), - Argument(&'a Argument<'a>), - AssignmentTarget(&'a AssignmentTarget<'a>), - SimpleAssignmentTarget(&'a SimpleAssignmentTarget<'a>), - AssignmentTargetWithDefault(&'a AssignmentTargetWithDefault<'a>), - ArrayExpressionElement(&'a ArrayExpressionElement<'a>), - Elision(&'a Elision), - ExpressionArrayElement(&'a Expression<'a>), - SpreadElement(&'a SpreadElement<'a>), - BindingRestElement(&'a BindingRestElement<'a>), - - Function(&'a Function<'a>), - FunctionBody(&'a FunctionBody<'a>), - FormalParameters(&'a FormalParameters<'a>), - FormalParameter(&'a FormalParameter<'a>), - CatchParameter(&'a CatchParameter<'a>), - - Class(&'a Class<'a>), - ClassBody(&'a ClassBody<'a>), - ClassHeritage(&'a Expression<'a>), - TSClassImplements(&'a TSClassImplements<'a>), - StaticBlock(&'a StaticBlock<'a>), - PropertyDefinition(&'a PropertyDefinition<'a>), - MethodDefinition(&'a MethodDefinition<'a>), - - ArrayPattern(&'a ArrayPattern<'a>), - ObjectPattern(&'a ObjectPattern<'a>), - AssignmentPattern(&'a AssignmentPattern<'a>), - - Decorator(&'a Decorator<'a>), - - ModuleDeclaration(&'a ModuleDeclaration<'a>), - ImportDeclaration(&'a ImportDeclaration<'a>), - ImportSpecifier(&'a ImportSpecifier<'a>), - ExportSpecifier(&'a ExportSpecifier<'a>), - ImportDefaultSpecifier(&'a ImportDefaultSpecifier<'a>), - ImportNamespaceSpecifier(&'a ImportNamespaceSpecifier<'a>), - ExportDefaultDeclaration(&'a ExportDefaultDeclaration<'a>), - ExportNamedDeclaration(&'a ExportNamedDeclaration<'a>), - ExportAllDeclaration(&'a ExportAllDeclaration<'a>), - - // JSX - // Please make sure to add these to `is_jsx` below. - JSXElement(&'a JSXElement<'a>), - JSXFragment(&'a JSXFragment<'a>), - JSXOpeningElement(&'a JSXOpeningElement<'a>), - JSXClosingElement(&'a JSXClosingElement<'a>), - JSXElementName(&'a JSXElementName<'a>), - JSXExpressionContainer(&'a JSXExpressionContainer<'a>), - JSXAttributeItem(&'a JSXAttributeItem<'a>), - JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>), - JSXText(&'a JSXText<'a>), - JSXIdentifier(&'a JSXIdentifier<'a>), - JSXMemberExpression(&'a JSXMemberExpression<'a>), - JSXMemberExpressionObject(&'a JSXMemberExpressionObject<'a>), - JSXNamespacedName(&'a JSXNamespacedName<'a>), - - // TypeScript - TSModuleBlock(&'a TSModuleBlock<'a>), - - // NOTE: make sure add these to AstKind::is_type below - TSAnyKeyword(&'a TSAnyKeyword), - TSBigIntKeyword(&'a TSBigIntKeyword), - TSBooleanKeyword(&'a TSBooleanKeyword), - TSIntrinsicKeyword(&'a TSIntrinsicKeyword), - TSNeverKeyword(&'a TSNeverKeyword), - TSNullKeyword(&'a TSNullKeyword), - TSNumberKeyword(&'a TSNumberKeyword), - TSObjectKeyword(&'a TSObjectKeyword), - TSStringKeyword(&'a TSStringKeyword), - TSSymbolKeyword(&'a TSSymbolKeyword), - TSUndefinedKeyword(&'a TSUndefinedKeyword), - TSUnknownKeyword(&'a TSUnknownKeyword), - TSVoidKeyword(&'a TSVoidKeyword), - - // NOTE: make sure add these to AstKind::is_type below - TSIndexedAccessType(&'a TSIndexedAccessType<'a>), - TSInferType(&'a TSInferType<'a>), - TSIntersectionType(&'a TSIntersectionType<'a>), - TSLiteralType(&'a TSLiteralType<'a>), - TSMethodSignature(&'a TSMethodSignature<'a>), - TSTemplateLiteralType(&'a TSTemplateLiteralType<'a>), - TSThisType(&'a TSThisType), - TSTypeLiteral(&'a TSTypeLiteral<'a>), - TSTypeReference(&'a TSTypeReference<'a>), - TSUnionType(&'a TSUnionType<'a>), - - TSAsExpression(&'a TSAsExpression<'a>), - TSSatisfiesExpression(&'a TSSatisfiesExpression<'a>), - TSNonNullExpression(&'a TSNonNullExpression<'a>), - TSInstantiationExpression(&'a TSInstantiationExpression<'a>), - - TSEnumDeclaration(&'a TSEnumDeclaration<'a>), - TSEnumMember(&'a TSEnumMember<'a>), - - TSImportEqualsDeclaration(&'a TSImportEqualsDeclaration<'a>), - TSTypeName(&'a TSTypeName<'a>), - TSExternalModuleReference(&'a TSExternalModuleReference<'a>), - TSQualifiedName(&'a TSQualifiedName<'a>), - - TSInterfaceDeclaration(&'a TSInterfaceDeclaration<'a>), - TSInterfaceHeritage(&'a TSInterfaceHeritage<'a>), - TSModuleDeclaration(&'a TSModuleDeclaration<'a>), - TSTypeAliasDeclaration(&'a TSTypeAliasDeclaration<'a>), - TSTypeAnnotation(&'a TSTypeAnnotation<'a>), - TSTypeQuery(&'a TSTypeQuery<'a>), - TSTypeAssertion(&'a TSTypeAssertion<'a>), - TSThisParameter(&'a TSThisParameter<'a>), - TSTypeParameter(&'a TSTypeParameter<'a>), - TSTypeParameterDeclaration(&'a TSTypeParameterDeclaration<'a>), - TSTypeParameterInstantiation(&'a TSTypeParameterInstantiation<'a>), - TSImportType(&'a TSImportType<'a>), - TSNamedTupleMember(&'a TSNamedTupleMember<'a>), - - TSPropertySignature(&'a TSPropertySignature<'a>), -} - -#[allow(unsafe_code)] -// SAFETY: -// The AST is part of the bump allocator, -// it is our responsibility to never simultaneously mutate across threads. -unsafe impl<'a> Send for AstKind<'a> {} -#[allow(unsafe_code)] -// SAFETY: -// The AST is part of the bump allocator, -// it is our responsibility to never simultaneously mutate across threads. -unsafe impl<'a> Sync for AstKind<'a> {} +use super::{ast::*, AstKind}; impl<'a> AstKind<'a> { #[rustfmt::skip] @@ -271,7 +53,7 @@ impl<'a> AstKind<'a> { | Self::StringLiteral(_) | Self::BooleanLiteral(_) | Self::NullLiteral(_) - | Self::BigintLiteral(_) + | Self::BigIntLiteral(_) | Self::RegExpLiteral(_) | Self::TemplateLiteral(_) ) @@ -316,7 +98,7 @@ impl<'a> AstKind<'a> { Expression::BooleanLiteral(e) => Self::BooleanLiteral(e), Expression::NullLiteral(e) => Self::NullLiteral(e), Expression::NumericLiteral(e) => Self::NumericLiteral(e), - Expression::BigintLiteral(e) => Self::BigintLiteral(e), + Expression::BigIntLiteral(e) => Self::BigIntLiteral(e), Expression::RegExpLiteral(e) => Self::RegExpLiteral(e), Expression::StringLiteral(e) => Self::StringLiteral(e), Expression::TemplateLiteral(e) => Self::TemplateLiteral(e), @@ -359,196 +141,6 @@ impl<'a> AstKind<'a> { } } -impl<'a> GetSpan for AstKind<'a> { - #[allow(clippy::match_same_arms)] - fn span(&self) -> Span { - match self { - Self::Program(x) => x.span, - Self::Directive(x) => x.span, - Self::Hashbang(x) => x.span, - - Self::BlockStatement(x) => x.span, - Self::BreakStatement(x) => x.span, - Self::ContinueStatement(x) => x.span, - Self::DebuggerStatement(x) => x.span, - Self::DoWhileStatement(x) => x.span, - Self::EmptyStatement(x) => x.span, - Self::ExpressionStatement(x) => x.span, - Self::ForInStatement(x) => x.span, - Self::ForOfStatement(x) => x.span, - Self::ForStatement(x) => x.span, - Self::ForStatementInit(x) => x.span(), - Self::IfStatement(x) => x.span, - Self::LabeledStatement(x) => x.span, - Self::ReturnStatement(x) => x.span, - Self::SwitchStatement(x) => x.span, - Self::ThrowStatement(x) => x.span, - Self::TryStatement(x) => x.span, - Self::WhileStatement(x) => x.span, - Self::WithStatement(x) => x.span, - - Self::SwitchCase(x) => x.span, - Self::CatchClause(x) => x.span, - Self::FinallyClause(x) => x.span, - - Self::VariableDeclaration(x) => x.span, - Self::VariableDeclarator(x) => x.span, - - Self::UsingDeclaration(x) => x.span, - - Self::IdentifierName(x) => x.span, - Self::IdentifierReference(x) => x.span, - Self::BindingIdentifier(x) => x.span, - Self::LabelIdentifier(x) => x.span, - Self::PrivateIdentifier(x) => x.span, - - Self::NumericLiteral(x) => x.span, - Self::StringLiteral(x) => x.span, - Self::BooleanLiteral(x) => x.span, - Self::NullLiteral(x) => x.span, - Self::BigintLiteral(x) => x.span, - Self::RegExpLiteral(x) => x.span, - Self::TemplateLiteral(x) => x.span, - - Self::MetaProperty(x) => x.span, - Self::Super(x) => x.span, - - Self::ArrayExpression(x) => x.span, - Self::ArrowFunctionExpression(x) => x.span, - Self::AssignmentExpression(x) => x.span, - Self::AwaitExpression(x) => x.span, - Self::BinaryExpression(x) => x.span, - Self::CallExpression(x) => x.span, - Self::ChainExpression(x) => x.span, - Self::ConditionalExpression(x) => x.span, - Self::LogicalExpression(x) => x.span, - Self::MemberExpression(x) => x.span(), - Self::NewExpression(x) => x.span, - Self::ObjectExpression(x) => x.span, - Self::ParenthesizedExpression(x) => x.span, - Self::SequenceExpression(x) => x.span, - Self::TaggedTemplateExpression(x) => x.span, - Self::ThisExpression(x) => x.span, - Self::UnaryExpression(x) => x.span, - Self::UpdateExpression(x) => x.span, - Self::YieldExpression(x) => x.span, - Self::ImportExpression(x) => x.span, - Self::PrivateInExpression(x) => x.span, - - Self::ObjectProperty(x) => x.span, - Self::PropertyKey(x) => x.span(), - Self::Argument(x) => x.span(), - Self::ArrayExpressionElement(x) => x.span(), - Self::AssignmentTarget(x) => x.span(), - Self::SimpleAssignmentTarget(x) => x.span(), - Self::AssignmentTargetWithDefault(x) => x.span, - Self::SpreadElement(x) => x.span, - Self::Elision(x) => x.span, - Self::ExpressionArrayElement(x) => x.span(), - Self::BindingRestElement(x) => x.span, - - Self::Function(x) => x.span, - Self::FunctionBody(x) => x.span, - Self::FormalParameters(x) => x.span, - Self::FormalParameter(x) => x.span, - Self::CatchParameter(x) => x.span, - - Self::Class(x) => x.span, - Self::ClassBody(x) => x.span, - Self::ClassHeritage(x) => x.span(), - Self::TSClassImplements(x) => x.span, - Self::StaticBlock(x) => x.span, - Self::PropertyDefinition(x) => x.span, - Self::MethodDefinition(x) => x.span, - - Self::ArrayPattern(x) => x.span, - Self::ObjectPattern(x) => x.span, - Self::AssignmentPattern(x) => x.span, - - Self::Decorator(x) => x.span, - - Self::ModuleDeclaration(x) => x.span(), - Self::ImportDeclaration(x) => x.span, - Self::ImportSpecifier(x) => x.span, - Self::ExportSpecifier(x) => x.span, - Self::ImportDefaultSpecifier(x) => x.span, - Self::ImportNamespaceSpecifier(x) => x.span, - Self::ExportDefaultDeclaration(x) => x.span, - Self::ExportNamedDeclaration(x) => x.span, - Self::ExportAllDeclaration(x) => x.span, - - Self::JSXOpeningElement(x) => x.span, - Self::JSXClosingElement(x) => x.span, - Self::JSXElementName(x) => x.span(), - Self::JSXElement(x) => x.span, - Self::JSXFragment(x) => x.span, - Self::JSXAttributeItem(x) => x.span(), - Self::JSXSpreadAttribute(x) => x.span, - Self::JSXText(x) => x.span, - Self::JSXExpressionContainer(x) => x.span, - Self::JSXIdentifier(x) => x.span, - Self::JSXMemberExpression(x) => x.span, - Self::JSXMemberExpressionObject(x) => x.span(), - Self::JSXNamespacedName(x) => x.span, - - Self::TSModuleBlock(x) => x.span, - - Self::TSAnyKeyword(x) => x.span, - Self::TSIntersectionType(x) => x.span, - Self::TSLiteralType(x) => x.span, - Self::TSMethodSignature(x) => x.span, - Self::TSNullKeyword(x) => x.span, - Self::TSTypeLiteral(x) => x.span, - Self::TSTypeReference(x) => x.span, - Self::TSUnionType(x) => x.span, - Self::TSVoidKeyword(x) => x.span, - Self::TSBigIntKeyword(x) => x.span, - Self::TSBooleanKeyword(x) => x.span, - Self::TSIntrinsicKeyword(x) => x.span, - Self::TSNeverKeyword(x) => x.span, - Self::TSNumberKeyword(x) => x.span, - Self::TSObjectKeyword(x) => x.span, - Self::TSStringKeyword(x) => x.span, - Self::TSSymbolKeyword(x) => x.span, - Self::TSThisType(x) => x.span, - Self::TSUndefinedKeyword(x) => x.span, - Self::TSUnknownKeyword(x) => x.span, - Self::TSInferType(x) => x.span, - Self::TSTemplateLiteralType(x) => x.span, - - Self::TSIndexedAccessType(x) => x.span, - - Self::TSAsExpression(x) => x.span, - Self::TSSatisfiesExpression(x) => x.span, - Self::TSNonNullExpression(x) => x.span, - Self::TSInstantiationExpression(x) => x.span, - - Self::TSEnumDeclaration(x) => x.span, - Self::TSEnumMember(x) => x.span, - - Self::TSImportEqualsDeclaration(x) => x.span, - Self::TSTypeName(x) => x.span(), - Self::TSExternalModuleReference(x) => x.span, - Self::TSQualifiedName(x) => x.span, - Self::TSInterfaceDeclaration(x) => x.span, - Self::TSInterfaceHeritage(x) => x.span, - Self::TSModuleDeclaration(x) => x.span, - Self::TSTypeAliasDeclaration(x) => x.span, - Self::TSTypeAnnotation(x) => x.span, - Self::TSTypeQuery(x) => x.span, - Self::TSTypeAssertion(x) => x.span, - Self::TSThisParameter(x) => x.span, - Self::TSTypeParameter(x) => x.span, - Self::TSTypeParameterDeclaration(x) => x.span, - Self::TSTypeParameterInstantiation(x) => x.span, - Self::TSImportType(x) => x.span, - Self::TSNamedTupleMember(x) => x.span, - - Self::TSPropertySignature(x) => x.span, - } - } -} - impl<'a> AstKind<'a> { #[allow(clippy::match_same_arms)] /// Get the AST kind name with minimal details. Particularly useful for @@ -601,7 +193,7 @@ impl<'a> AstKind<'a> { Self::StringLiteral(s) => format!("StringLiteral({})", s.value).into(), Self::BooleanLiteral(b) => format!("BooleanLiteral({})", b.value).into(), Self::NullLiteral(_) => "NullLiteral".into(), - Self::BigintLiteral(b) => format!("BigintLiteral({})", b.raw).into(), + Self::BigIntLiteral(b) => format!("BigIntLiteral({})", b.raw).into(), Self::RegExpLiteral(r) => format!("RegExpLiteral({})", r.regex).into(), Self::TemplateLiteral(t) => format!( "TemplateLiteral({})", diff --git a/crates/oxc_ast/src/generated/ast_kind.rs b/crates/oxc_ast/src/generated/ast_kind.rs new file mode 100644 index 0000000000000..0d8d9b1e3920e --- /dev/null +++ b/crates/oxc_ast/src/generated/ast_kind.rs @@ -0,0 +1,502 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_codegen/src/generators/ast_kind.rs` + +use crate::ast::*; +use oxc_span::{GetSpan, Span}; + +#[derive(Debug, Clone, Copy)] +pub enum AstType { + BooleanLiteral, + NullLiteral, + NumericLiteral, + BigIntLiteral, + RegExpLiteral, + StringLiteral, + Program, + IdentifierName, + IdentifierReference, + BindingIdentifier, + LabelIdentifier, + ThisExpression, + ArrayExpression, + ArrayExpressionElement, + Elision, + ObjectExpression, + ObjectProperty, + PropertyKey, + TemplateLiteral, + TaggedTemplateExpression, + MemberExpression, + CallExpression, + NewExpression, + MetaProperty, + SpreadElement, + Argument, + UpdateExpression, + UnaryExpression, + BinaryExpression, + PrivateInExpression, + LogicalExpression, + ConditionalExpression, + AssignmentExpression, + AssignmentTarget, + SimpleAssignmentTarget, + AssignmentTargetWithDefault, + SequenceExpression, + Super, + AwaitExpression, + ChainExpression, + ParenthesizedExpression, + Directive, + Hashbang, + BlockStatement, + VariableDeclaration, + VariableDeclarator, + UsingDeclaration, + EmptyStatement, + ExpressionStatement, + IfStatement, + DoWhileStatement, + WhileStatement, + ForStatement, + ForStatementInit, + ForInStatement, + ForOfStatement, + ContinueStatement, + BreakStatement, + ReturnStatement, + WithStatement, + SwitchStatement, + SwitchCase, + LabeledStatement, + ThrowStatement, + TryStatement, + CatchClause, + CatchParameter, + DebuggerStatement, + AssignmentPattern, + ObjectPattern, + ArrayPattern, + BindingRestElement, + Function, + FormalParameters, + FormalParameter, + FunctionBody, + ArrowFunctionExpression, + YieldExpression, + Class, + ClassBody, + MethodDefinition, + PropertyDefinition, + PrivateIdentifier, + StaticBlock, + ModuleDeclaration, + ImportExpression, + ImportDeclaration, + ImportSpecifier, + ImportDefaultSpecifier, + ImportNamespaceSpecifier, + ExportNamedDeclaration, + ExportDefaultDeclaration, + ExportAllDeclaration, + ExportSpecifier, + TSThisParameter, + TSEnumDeclaration, + TSEnumMember, + TSTypeAnnotation, + TSLiteralType, + TSUnionType, + TSIntersectionType, + TSIndexedAccessType, + TSNamedTupleMember, + TSAnyKeyword, + TSStringKeyword, + TSBooleanKeyword, + TSNumberKeyword, + TSNeverKeyword, + TSIntrinsicKeyword, + TSUnknownKeyword, + TSNullKeyword, + TSUndefinedKeyword, + TSVoidKeyword, + TSSymbolKeyword, + TSThisType, + TSObjectKeyword, + TSBigIntKeyword, + TSTypeReference, + TSTypeName, + TSQualifiedName, + TSTypeParameterInstantiation, + TSTypeParameter, + TSTypeParameterDeclaration, + TSTypeAliasDeclaration, + TSClassImplements, + TSInterfaceDeclaration, + TSPropertySignature, + TSMethodSignature, + TSInterfaceHeritage, + TSModuleDeclaration, + TSModuleBlock, + TSTypeLiteral, + TSInferType, + TSTypeQuery, + TSImportType, + TSTemplateLiteralType, + TSAsExpression, + TSSatisfiesExpression, + TSTypeAssertion, + TSImportEqualsDeclaration, + TSExternalModuleReference, + TSNonNullExpression, + Decorator, + TSInstantiationExpression, + JSXElement, + JSXOpeningElement, + JSXClosingElement, + JSXFragment, + JSXElementName, + JSXNamespacedName, + JSXMemberExpression, + JSXMemberExpressionObject, + JSXExpressionContainer, + JSXAttributeItem, + JSXSpreadAttribute, + JSXIdentifier, + JSXText, + FinallyClause, + ClassHeritage, + ExpressionArrayElement, +} + +/// Untyped AST Node Kind +#[derive(Debug, Clone, Copy)] +pub enum AstKind<'a> { + BooleanLiteral(&'a BooleanLiteral), + NullLiteral(&'a NullLiteral), + NumericLiteral(&'a NumericLiteral<'a>), + BigIntLiteral(&'a BigIntLiteral<'a>), + RegExpLiteral(&'a RegExpLiteral<'a>), + StringLiteral(&'a StringLiteral<'a>), + Program(&'a Program<'a>), + IdentifierName(&'a IdentifierName<'a>), + IdentifierReference(&'a IdentifierReference<'a>), + BindingIdentifier(&'a BindingIdentifier<'a>), + LabelIdentifier(&'a LabelIdentifier<'a>), + ThisExpression(&'a ThisExpression), + ArrayExpression(&'a ArrayExpression<'a>), + ArrayExpressionElement(&'a ArrayExpressionElement<'a>), + Elision(&'a Elision), + ObjectExpression(&'a ObjectExpression<'a>), + ObjectProperty(&'a ObjectProperty<'a>), + PropertyKey(&'a PropertyKey<'a>), + TemplateLiteral(&'a TemplateLiteral<'a>), + TaggedTemplateExpression(&'a TaggedTemplateExpression<'a>), + MemberExpression(&'a MemberExpression<'a>), + CallExpression(&'a CallExpression<'a>), + NewExpression(&'a NewExpression<'a>), + MetaProperty(&'a MetaProperty<'a>), + SpreadElement(&'a SpreadElement<'a>), + Argument(&'a Argument<'a>), + UpdateExpression(&'a UpdateExpression<'a>), + UnaryExpression(&'a UnaryExpression<'a>), + BinaryExpression(&'a BinaryExpression<'a>), + PrivateInExpression(&'a PrivateInExpression<'a>), + LogicalExpression(&'a LogicalExpression<'a>), + ConditionalExpression(&'a ConditionalExpression<'a>), + AssignmentExpression(&'a AssignmentExpression<'a>), + AssignmentTarget(&'a AssignmentTarget<'a>), + SimpleAssignmentTarget(&'a SimpleAssignmentTarget<'a>), + AssignmentTargetWithDefault(&'a AssignmentTargetWithDefault<'a>), + SequenceExpression(&'a SequenceExpression<'a>), + Super(&'a Super), + AwaitExpression(&'a AwaitExpression<'a>), + ChainExpression(&'a ChainExpression<'a>), + ParenthesizedExpression(&'a ParenthesizedExpression<'a>), + Directive(&'a Directive<'a>), + Hashbang(&'a Hashbang<'a>), + BlockStatement(&'a BlockStatement<'a>), + VariableDeclaration(&'a VariableDeclaration<'a>), + VariableDeclarator(&'a VariableDeclarator<'a>), + UsingDeclaration(&'a UsingDeclaration<'a>), + EmptyStatement(&'a EmptyStatement), + ExpressionStatement(&'a ExpressionStatement<'a>), + IfStatement(&'a IfStatement<'a>), + DoWhileStatement(&'a DoWhileStatement<'a>), + WhileStatement(&'a WhileStatement<'a>), + ForStatement(&'a ForStatement<'a>), + ForStatementInit(&'a ForStatementInit<'a>), + ForInStatement(&'a ForInStatement<'a>), + ForOfStatement(&'a ForOfStatement<'a>), + ContinueStatement(&'a ContinueStatement<'a>), + BreakStatement(&'a BreakStatement<'a>), + ReturnStatement(&'a ReturnStatement<'a>), + WithStatement(&'a WithStatement<'a>), + SwitchStatement(&'a SwitchStatement<'a>), + SwitchCase(&'a SwitchCase<'a>), + LabeledStatement(&'a LabeledStatement<'a>), + ThrowStatement(&'a ThrowStatement<'a>), + TryStatement(&'a TryStatement<'a>), + CatchClause(&'a CatchClause<'a>), + CatchParameter(&'a CatchParameter<'a>), + DebuggerStatement(&'a DebuggerStatement), + AssignmentPattern(&'a AssignmentPattern<'a>), + ObjectPattern(&'a ObjectPattern<'a>), + ArrayPattern(&'a ArrayPattern<'a>), + BindingRestElement(&'a BindingRestElement<'a>), + Function(&'a Function<'a>), + FormalParameters(&'a FormalParameters<'a>), + FormalParameter(&'a FormalParameter<'a>), + FunctionBody(&'a FunctionBody<'a>), + ArrowFunctionExpression(&'a ArrowFunctionExpression<'a>), + YieldExpression(&'a YieldExpression<'a>), + Class(&'a Class<'a>), + ClassBody(&'a ClassBody<'a>), + MethodDefinition(&'a MethodDefinition<'a>), + PropertyDefinition(&'a PropertyDefinition<'a>), + PrivateIdentifier(&'a PrivateIdentifier<'a>), + StaticBlock(&'a StaticBlock<'a>), + ModuleDeclaration(&'a ModuleDeclaration<'a>), + ImportExpression(&'a ImportExpression<'a>), + ImportDeclaration(&'a ImportDeclaration<'a>), + ImportSpecifier(&'a ImportSpecifier<'a>), + ImportDefaultSpecifier(&'a ImportDefaultSpecifier<'a>), + ImportNamespaceSpecifier(&'a ImportNamespaceSpecifier<'a>), + ExportNamedDeclaration(&'a ExportNamedDeclaration<'a>), + ExportDefaultDeclaration(&'a ExportDefaultDeclaration<'a>), + ExportAllDeclaration(&'a ExportAllDeclaration<'a>), + ExportSpecifier(&'a ExportSpecifier<'a>), + TSThisParameter(&'a TSThisParameter<'a>), + TSEnumDeclaration(&'a TSEnumDeclaration<'a>), + TSEnumMember(&'a TSEnumMember<'a>), + TSTypeAnnotation(&'a TSTypeAnnotation<'a>), + TSLiteralType(&'a TSLiteralType<'a>), + TSUnionType(&'a TSUnionType<'a>), + TSIntersectionType(&'a TSIntersectionType<'a>), + TSIndexedAccessType(&'a TSIndexedAccessType<'a>), + TSNamedTupleMember(&'a TSNamedTupleMember<'a>), + TSAnyKeyword(&'a TSAnyKeyword), + TSStringKeyword(&'a TSStringKeyword), + TSBooleanKeyword(&'a TSBooleanKeyword), + TSNumberKeyword(&'a TSNumberKeyword), + TSNeverKeyword(&'a TSNeverKeyword), + TSIntrinsicKeyword(&'a TSIntrinsicKeyword), + TSUnknownKeyword(&'a TSUnknownKeyword), + TSNullKeyword(&'a TSNullKeyword), + TSUndefinedKeyword(&'a TSUndefinedKeyword), + TSVoidKeyword(&'a TSVoidKeyword), + TSSymbolKeyword(&'a TSSymbolKeyword), + TSThisType(&'a TSThisType), + TSObjectKeyword(&'a TSObjectKeyword), + TSBigIntKeyword(&'a TSBigIntKeyword), + TSTypeReference(&'a TSTypeReference<'a>), + TSTypeName(&'a TSTypeName<'a>), + TSQualifiedName(&'a TSQualifiedName<'a>), + TSTypeParameterInstantiation(&'a TSTypeParameterInstantiation<'a>), + TSTypeParameter(&'a TSTypeParameter<'a>), + TSTypeParameterDeclaration(&'a TSTypeParameterDeclaration<'a>), + TSTypeAliasDeclaration(&'a TSTypeAliasDeclaration<'a>), + TSClassImplements(&'a TSClassImplements<'a>), + TSInterfaceDeclaration(&'a TSInterfaceDeclaration<'a>), + TSPropertySignature(&'a TSPropertySignature<'a>), + TSMethodSignature(&'a TSMethodSignature<'a>), + TSInterfaceHeritage(&'a TSInterfaceHeritage<'a>), + TSModuleDeclaration(&'a TSModuleDeclaration<'a>), + TSModuleBlock(&'a TSModuleBlock<'a>), + TSTypeLiteral(&'a TSTypeLiteral<'a>), + TSInferType(&'a TSInferType<'a>), + TSTypeQuery(&'a TSTypeQuery<'a>), + TSImportType(&'a TSImportType<'a>), + TSTemplateLiteralType(&'a TSTemplateLiteralType<'a>), + TSAsExpression(&'a TSAsExpression<'a>), + TSSatisfiesExpression(&'a TSSatisfiesExpression<'a>), + TSTypeAssertion(&'a TSTypeAssertion<'a>), + TSImportEqualsDeclaration(&'a TSImportEqualsDeclaration<'a>), + TSExternalModuleReference(&'a TSExternalModuleReference<'a>), + TSNonNullExpression(&'a TSNonNullExpression<'a>), + Decorator(&'a Decorator<'a>), + TSInstantiationExpression(&'a TSInstantiationExpression<'a>), + JSXElement(&'a JSXElement<'a>), + JSXOpeningElement(&'a JSXOpeningElement<'a>), + JSXClosingElement(&'a JSXClosingElement<'a>), + JSXFragment(&'a JSXFragment<'a>), + JSXElementName(&'a JSXElementName<'a>), + JSXNamespacedName(&'a JSXNamespacedName<'a>), + JSXMemberExpression(&'a JSXMemberExpression<'a>), + JSXMemberExpressionObject(&'a JSXMemberExpressionObject<'a>), + JSXExpressionContainer(&'a JSXExpressionContainer<'a>), + JSXAttributeItem(&'a JSXAttributeItem<'a>), + JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>), + JSXIdentifier(&'a JSXIdentifier<'a>), + JSXText(&'a JSXText<'a>), + FinallyClause(&'a BlockStatement<'a>), + ClassHeritage(&'a Expression<'a>), + ExpressionArrayElement(&'a Expression<'a>), +} + +impl<'a> GetSpan for AstKind<'a> { + #[allow(clippy::match_same_arms)] + fn span(&self) -> Span { + match self { + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::Program(it) => it.span(), + Self::IdentifierName(it) => it.span(), + Self::IdentifierReference(it) => it.span(), + Self::BindingIdentifier(it) => it.span(), + Self::LabelIdentifier(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrayExpressionElement(it) => it.span(), + Self::Elision(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ObjectProperty(it) => it.span(), + Self::PropertyKey(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::MemberExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::SpreadElement(it) => it.span(), + Self::Argument(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AssignmentTarget(it) => it.span(), + Self::SimpleAssignmentTarget(it) => it.span(), + Self::AssignmentTargetWithDefault(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::Super(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::Directive(it) => it.span(), + Self::Hashbang(it) => it.span(), + Self::BlockStatement(it) => it.span(), + Self::VariableDeclaration(it) => it.span(), + Self::VariableDeclarator(it) => it.span(), + Self::UsingDeclaration(it) => it.span(), + Self::EmptyStatement(it) => it.span(), + Self::ExpressionStatement(it) => it.span(), + Self::IfStatement(it) => it.span(), + Self::DoWhileStatement(it) => it.span(), + Self::WhileStatement(it) => it.span(), + Self::ForStatement(it) => it.span(), + Self::ForStatementInit(it) => it.span(), + Self::ForInStatement(it) => it.span(), + Self::ForOfStatement(it) => it.span(), + Self::ContinueStatement(it) => it.span(), + Self::BreakStatement(it) => it.span(), + Self::ReturnStatement(it) => it.span(), + Self::WithStatement(it) => it.span(), + Self::SwitchStatement(it) => it.span(), + Self::SwitchCase(it) => it.span(), + Self::LabeledStatement(it) => it.span(), + Self::ThrowStatement(it) => it.span(), + Self::TryStatement(it) => it.span(), + Self::CatchClause(it) => it.span(), + Self::CatchParameter(it) => it.span(), + Self::DebuggerStatement(it) => it.span(), + Self::AssignmentPattern(it) => it.span(), + Self::ObjectPattern(it) => it.span(), + Self::ArrayPattern(it) => it.span(), + Self::BindingRestElement(it) => it.span(), + Self::Function(it) => it.span(), + Self::FormalParameters(it) => it.span(), + Self::FormalParameter(it) => it.span(), + Self::FunctionBody(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::Class(it) => it.span(), + Self::ClassBody(it) => it.span(), + Self::MethodDefinition(it) => it.span(), + Self::PropertyDefinition(it) => it.span(), + Self::PrivateIdentifier(it) => it.span(), + Self::StaticBlock(it) => it.span(), + Self::ModuleDeclaration(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::ImportDeclaration(it) => it.span(), + Self::ImportSpecifier(it) => it.span(), + Self::ImportDefaultSpecifier(it) => it.span(), + Self::ImportNamespaceSpecifier(it) => it.span(), + Self::ExportNamedDeclaration(it) => it.span(), + Self::ExportDefaultDeclaration(it) => it.span(), + Self::ExportAllDeclaration(it) => it.span(), + Self::ExportSpecifier(it) => it.span(), + Self::TSThisParameter(it) => it.span(), + Self::TSEnumDeclaration(it) => it.span(), + Self::TSEnumMember(it) => it.span(), + Self::TSTypeAnnotation(it) => it.span(), + Self::TSLiteralType(it) => it.span(), + Self::TSUnionType(it) => it.span(), + Self::TSIntersectionType(it) => it.span(), + Self::TSIndexedAccessType(it) => it.span(), + Self::TSNamedTupleMember(it) => it.span(), + Self::TSAnyKeyword(it) => it.span(), + Self::TSStringKeyword(it) => it.span(), + Self::TSBooleanKeyword(it) => it.span(), + Self::TSNumberKeyword(it) => it.span(), + Self::TSNeverKeyword(it) => it.span(), + Self::TSIntrinsicKeyword(it) => it.span(), + Self::TSUnknownKeyword(it) => it.span(), + Self::TSNullKeyword(it) => it.span(), + Self::TSUndefinedKeyword(it) => it.span(), + Self::TSVoidKeyword(it) => it.span(), + Self::TSSymbolKeyword(it) => it.span(), + Self::TSThisType(it) => it.span(), + Self::TSObjectKeyword(it) => it.span(), + Self::TSBigIntKeyword(it) => it.span(), + Self::TSTypeReference(it) => it.span(), + Self::TSTypeName(it) => it.span(), + Self::TSQualifiedName(it) => it.span(), + Self::TSTypeParameterInstantiation(it) => it.span(), + Self::TSTypeParameter(it) => it.span(), + Self::TSTypeParameterDeclaration(it) => it.span(), + Self::TSTypeAliasDeclaration(it) => it.span(), + Self::TSClassImplements(it) => it.span(), + Self::TSInterfaceDeclaration(it) => it.span(), + Self::TSPropertySignature(it) => it.span(), + Self::TSMethodSignature(it) => it.span(), + Self::TSInterfaceHeritage(it) => it.span(), + Self::TSModuleDeclaration(it) => it.span(), + Self::TSModuleBlock(it) => it.span(), + Self::TSTypeLiteral(it) => it.span(), + Self::TSInferType(it) => it.span(), + Self::TSTypeQuery(it) => it.span(), + Self::TSImportType(it) => it.span(), + Self::TSTemplateLiteralType(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSImportEqualsDeclaration(it) => it.span(), + Self::TSExternalModuleReference(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::Decorator(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXOpeningElement(it) => it.span(), + Self::JSXClosingElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::JSXElementName(it) => it.span(), + Self::JSXNamespacedName(it) => it.span(), + Self::JSXMemberExpression(it) => it.span(), + Self::JSXMemberExpressionObject(it) => it.span(), + Self::JSXExpressionContainer(it) => it.span(), + Self::JSXAttributeItem(it) => it.span(), + Self::JSXSpreadAttribute(it) => it.span(), + Self::JSXIdentifier(it) => it.span(), + Self::JSXText(it) => it.span(), + Self::FinallyClause(it) => it.span(), + Self::ClassHeritage(it) => it.span(), + Self::ExpressionArrayElement(it) => it.span(), + } + } +} diff --git a/crates/oxc_ast/src/generated/span.rs b/crates/oxc_ast/src/generated/span.rs new file mode 100644 index 0000000000000..60f3e3ff46a3e --- /dev/null +++ b/crates/oxc_ast/src/generated/span.rs @@ -0,0 +1,2175 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_codegen/src/generators/impl_get_span.rs` + +#![allow(clippy::match_same_arms)] + +use crate::ast::*; +use oxc_span::{GetSpan, Span}; + +impl GetSpan for BooleanLiteral { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for NullLiteral { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for NumericLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BigIntLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for RegExpLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for StringLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Program<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Expression<'a> { + fn span(&self) -> Span { + match self { + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for IdentifierName<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for IdentifierReference<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BindingIdentifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for LabelIdentifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for ThisExpression { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ArrayExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ArrayExpressionElement<'a> { + fn span(&self) -> Span { + match self { + Self::SpreadElement(it) => it.span(), + Self::Elision(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl GetSpan for Elision { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ObjectExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ObjectPropertyKind<'a> { + fn span(&self) -> Span { + match self { + Self::ObjectProperty(it) => it.span(), + Self::SpreadProperty(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ObjectProperty<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for PropertyKey<'a> { + fn span(&self) -> Span { + match self { + Self::StaticIdentifier(it) => it.span(), + Self::PrivateIdentifier(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TemplateLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TaggedTemplateExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TemplateElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for MemberExpression<'a> { + fn span(&self) -> Span { + match self { + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ComputedMemberExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for StaticMemberExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for PrivateFieldExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for CallExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for NewExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for MetaProperty<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for SpreadElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Argument<'a> { + fn span(&self) -> Span { + match self { + Self::SpreadElement(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for UpdateExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for UnaryExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BinaryExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for PrivateInExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for LogicalExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ConditionalExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentTarget<'a> { + fn span(&self) -> Span { + match self { + Self::AssignmentTargetIdentifier(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + Self::ArrayAssignmentTarget(it) => it.span(), + Self::ObjectAssignmentTarget(it) => it.span(), + } + } +} + +impl<'a> GetSpan for SimpleAssignmentTarget<'a> { + fn span(&self) -> Span { + match self { + Self::AssignmentTargetIdentifier(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for AssignmentTargetPattern<'a> { + fn span(&self) -> Span { + match self { + Self::ArrayAssignmentTarget(it) => it.span(), + Self::ObjectAssignmentTarget(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ArrayAssignmentTarget<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ObjectAssignmentTarget<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentTargetRest<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentTargetMaybeDefault<'a> { + fn span(&self) -> Span { + match self { + Self::AssignmentTargetWithDefault(it) => it.span(), + Self::AssignmentTargetIdentifier(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + Self::ArrayAssignmentTarget(it) => it.span(), + Self::ObjectAssignmentTarget(it) => it.span(), + } + } +} + +impl<'a> GetSpan for AssignmentTargetWithDefault<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentTargetProperty<'a> { + fn span(&self) -> Span { + match self { + Self::AssignmentTargetPropertyIdentifier(it) => it.span(), + Self::AssignmentTargetPropertyProperty(it) => it.span(), + } + } +} + +impl<'a> GetSpan for AssignmentTargetPropertyIdentifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AssignmentTargetPropertyProperty<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for SequenceExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for Super { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for AwaitExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ChainExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ChainElement<'a> { + fn span(&self) -> Span { + match self { + Self::CallExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ParenthesizedExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Statement<'a> { + fn span(&self) -> Span { + match self { + Self::BlockStatement(it) => it.span(), + Self::BreakStatement(it) => it.span(), + Self::ContinueStatement(it) => it.span(), + Self::DebuggerStatement(it) => it.span(), + Self::DoWhileStatement(it) => it.span(), + Self::EmptyStatement(it) => it.span(), + Self::ExpressionStatement(it) => it.span(), + Self::ForInStatement(it) => it.span(), + Self::ForOfStatement(it) => it.span(), + Self::ForStatement(it) => it.span(), + Self::IfStatement(it) => it.span(), + Self::LabeledStatement(it) => it.span(), + Self::ReturnStatement(it) => it.span(), + Self::SwitchStatement(it) => it.span(), + Self::ThrowStatement(it) => it.span(), + Self::TryStatement(it) => it.span(), + Self::WhileStatement(it) => it.span(), + Self::WithStatement(it) => it.span(), + Self::VariableDeclaration(it) => it.span(), + Self::FunctionDeclaration(it) => it.span(), + Self::ClassDeclaration(it) => it.span(), + Self::UsingDeclaration(it) => it.span(), + Self::TSTypeAliasDeclaration(it) => it.span(), + Self::TSInterfaceDeclaration(it) => it.span(), + Self::TSEnumDeclaration(it) => it.span(), + Self::TSModuleDeclaration(it) => it.span(), + Self::TSImportEqualsDeclaration(it) => it.span(), + Self::ImportDeclaration(it) => it.span(), + Self::ExportAllDeclaration(it) => it.span(), + Self::ExportDefaultDeclaration(it) => it.span(), + Self::ExportNamedDeclaration(it) => it.span(), + Self::TSExportAssignment(it) => it.span(), + Self::TSNamespaceExportDeclaration(it) => it.span(), + } + } +} + +impl<'a> GetSpan for Directive<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Hashbang<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BlockStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Declaration<'a> { + fn span(&self) -> Span { + match self { + Self::VariableDeclaration(it) => it.span(), + Self::FunctionDeclaration(it) => it.span(), + Self::ClassDeclaration(it) => it.span(), + Self::UsingDeclaration(it) => it.span(), + Self::TSTypeAliasDeclaration(it) => it.span(), + Self::TSInterfaceDeclaration(it) => it.span(), + Self::TSEnumDeclaration(it) => it.span(), + Self::TSModuleDeclaration(it) => it.span(), + Self::TSImportEqualsDeclaration(it) => it.span(), + } + } +} + +impl<'a> GetSpan for VariableDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for VariableDeclarator<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for UsingDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for EmptyStatement { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ExpressionStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for IfStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for DoWhileStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for WhileStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ForStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ForStatementInit<'a> { + fn span(&self) -> Span { + match self { + Self::VariableDeclaration(it) => it.span(), + Self::UsingDeclaration(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ForInStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ForStatementLeft<'a> { + fn span(&self) -> Span { + match self { + Self::VariableDeclaration(it) => it.span(), + Self::UsingDeclaration(it) => it.span(), + Self::AssignmentTargetIdentifier(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + Self::ArrayAssignmentTarget(it) => it.span(), + Self::ObjectAssignmentTarget(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ForOfStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ContinueStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BreakStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ReturnStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for WithStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for SwitchStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for SwitchCase<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for LabeledStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ThrowStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TryStatement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for CatchClause<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for CatchParameter<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for DebuggerStatement { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BindingPatternKind<'a> { + fn span(&self) -> Span { + match self { + Self::BindingIdentifier(it) => it.span(), + Self::ObjectPattern(it) => it.span(), + Self::ArrayPattern(it) => it.span(), + Self::AssignmentPattern(it) => it.span(), + } + } +} + +impl<'a> GetSpan for AssignmentPattern<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ObjectPattern<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BindingProperty<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ArrayPattern<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BindingRestElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Function<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for FormalParameters<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for FormalParameter<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for FunctionBody<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ArrowFunctionExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for YieldExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Class<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ClassBody<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ClassElement<'a> { + fn span(&self) -> Span { + match self { + Self::StaticBlock(it) => it.span(), + Self::MethodDefinition(it) => it.span(), + Self::PropertyDefinition(it) => it.span(), + Self::AccessorProperty(it) => it.span(), + Self::TSIndexSignature(it) => it.span(), + } + } +} + +impl<'a> GetSpan for MethodDefinition<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for PropertyDefinition<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for PrivateIdentifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for StaticBlock<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ModuleDeclaration<'a> { + fn span(&self) -> Span { + match self { + Self::ImportDeclaration(it) => it.span(), + Self::ExportAllDeclaration(it) => it.span(), + Self::ExportDefaultDeclaration(it) => it.span(), + Self::ExportNamedDeclaration(it) => it.span(), + Self::TSExportAssignment(it) => it.span(), + Self::TSNamespaceExportDeclaration(it) => it.span(), + } + } +} + +impl<'a> GetSpan for AccessorProperty<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportDeclarationSpecifier<'a> { + fn span(&self) -> Span { + match self { + Self::ImportSpecifier(it) => it.span(), + Self::ImportDefaultSpecifier(it) => it.span(), + Self::ImportNamespaceSpecifier(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ImportSpecifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportDefaultSpecifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportNamespaceSpecifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for WithClause<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportAttribute<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ImportAttributeKey<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::StringLiteral(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ExportNamedDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ExportDefaultDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ExportAllDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ExportSpecifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for ExportDefaultDeclarationKind<'a> { + fn span(&self) -> Span { + match self { + Self::FunctionDeclaration(it) => it.span(), + Self::ClassDeclaration(it) => it.span(), + Self::TSInterfaceDeclaration(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for ModuleExportName<'a> { + fn span(&self) -> Span { + match self { + Self::IdentifierName(it) => it.span(), + Self::IdentifierReference(it) => it.span(), + Self::StringLiteral(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSThisParameter<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSEnumDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSEnumMember<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSEnumMemberName<'a> { + fn span(&self) -> Span { + match self { + Self::StaticIdentifier(it) => it.span(), + Self::StaticStringLiteral(it) => it.span(), + Self::StaticNumericLiteral(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSTypeAnnotation<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSLiteralType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSLiteral<'a> { + fn span(&self) -> Span { + match self { + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSType<'a> { + fn span(&self) -> Span { + match self { + Self::TSAnyKeyword(it) => it.span(), + Self::TSBigIntKeyword(it) => it.span(), + Self::TSBooleanKeyword(it) => it.span(), + Self::TSIntrinsicKeyword(it) => it.span(), + Self::TSNeverKeyword(it) => it.span(), + Self::TSNullKeyword(it) => it.span(), + Self::TSNumberKeyword(it) => it.span(), + Self::TSObjectKeyword(it) => it.span(), + Self::TSStringKeyword(it) => it.span(), + Self::TSSymbolKeyword(it) => it.span(), + Self::TSThisType(it) => it.span(), + Self::TSUndefinedKeyword(it) => it.span(), + Self::TSUnknownKeyword(it) => it.span(), + Self::TSVoidKeyword(it) => it.span(), + Self::TSArrayType(it) => it.span(), + Self::TSConditionalType(it) => it.span(), + Self::TSConstructorType(it) => it.span(), + Self::TSFunctionType(it) => it.span(), + Self::TSImportType(it) => it.span(), + Self::TSIndexedAccessType(it) => it.span(), + Self::TSInferType(it) => it.span(), + Self::TSIntersectionType(it) => it.span(), + Self::TSLiteralType(it) => it.span(), + Self::TSMappedType(it) => it.span(), + Self::TSNamedTupleMember(it) => it.span(), + Self::TSQualifiedName(it) => it.span(), + Self::TSTemplateLiteralType(it) => it.span(), + Self::TSTupleType(it) => it.span(), + Self::TSTypeLiteral(it) => it.span(), + Self::TSTypeOperatorType(it) => it.span(), + Self::TSTypePredicate(it) => it.span(), + Self::TSTypeQuery(it) => it.span(), + Self::TSTypeReference(it) => it.span(), + Self::TSUnionType(it) => it.span(), + Self::JSDocNullableType(it) => it.span(), + Self::JSDocUnknownType(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSConditionalType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSUnionType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSIntersectionType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeOperator<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSArrayType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSIndexedAccessType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTupleType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSNamedTupleMember<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSOptionalType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSRestType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTupleElement<'a> { + fn span(&self) -> Span { + match self { + Self::TSOptionalType(it) => it.span(), + Self::TSRestType(it) => it.span(), + Self::TSAnyKeyword(it) => it.span(), + Self::TSBigIntKeyword(it) => it.span(), + Self::TSBooleanKeyword(it) => it.span(), + Self::TSIntrinsicKeyword(it) => it.span(), + Self::TSNeverKeyword(it) => it.span(), + Self::TSNullKeyword(it) => it.span(), + Self::TSNumberKeyword(it) => it.span(), + Self::TSObjectKeyword(it) => it.span(), + Self::TSStringKeyword(it) => it.span(), + Self::TSSymbolKeyword(it) => it.span(), + Self::TSThisType(it) => it.span(), + Self::TSUndefinedKeyword(it) => it.span(), + Self::TSUnknownKeyword(it) => it.span(), + Self::TSVoidKeyword(it) => it.span(), + Self::TSArrayType(it) => it.span(), + Self::TSConditionalType(it) => it.span(), + Self::TSConstructorType(it) => it.span(), + Self::TSFunctionType(it) => it.span(), + Self::TSImportType(it) => it.span(), + Self::TSIndexedAccessType(it) => it.span(), + Self::TSInferType(it) => it.span(), + Self::TSIntersectionType(it) => it.span(), + Self::TSLiteralType(it) => it.span(), + Self::TSMappedType(it) => it.span(), + Self::TSNamedTupleMember(it) => it.span(), + Self::TSQualifiedName(it) => it.span(), + Self::TSTemplateLiteralType(it) => it.span(), + Self::TSTupleType(it) => it.span(), + Self::TSTypeLiteral(it) => it.span(), + Self::TSTypeOperatorType(it) => it.span(), + Self::TSTypePredicate(it) => it.span(), + Self::TSTypeQuery(it) => it.span(), + Self::TSTypeReference(it) => it.span(), + Self::TSUnionType(it) => it.span(), + Self::JSDocNullableType(it) => it.span(), + Self::JSDocUnknownType(it) => it.span(), + } + } +} + +impl GetSpan for TSAnyKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSStringKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSBooleanKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSNumberKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSNeverKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSIntrinsicKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSUnknownKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSNullKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSUndefinedKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSVoidKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSSymbolKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSThisType { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSObjectKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for TSBigIntKeyword { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeReference<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeName<'a> { + fn span(&self) -> Span { + match self { + Self::IdentifierReference(it) => it.span(), + Self::QualifiedName(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSQualifiedName<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeParameterInstantiation<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeParameter<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeParameterDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeAliasDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSClassImplements<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSInterfaceDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSInterfaceBody<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSPropertySignature<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSSignature<'a> { + fn span(&self) -> Span { + match self { + Self::TSIndexSignature(it) => it.span(), + Self::TSPropertySignature(it) => it.span(), + Self::TSCallSignatureDeclaration(it) => it.span(), + Self::TSConstructSignatureDeclaration(it) => it.span(), + Self::TSMethodSignature(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSIndexSignature<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSCallSignatureDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSMethodSignature<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSConstructSignatureDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSIndexSignatureName<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSInterfaceHeritage<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypePredicate<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypePredicateName<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::This(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSModuleDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSModuleDeclarationName<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::StringLiteral(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSModuleDeclarationBody<'a> { + fn span(&self) -> Span { + match self { + Self::TSModuleDeclaration(it) => it.span(), + Self::TSModuleBlock(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSModuleBlock<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeLiteral<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSInferType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeQuery<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeQueryExprName<'a> { + fn span(&self) -> Span { + match self { + Self::TSImportType(it) => it.span(), + Self::IdentifierReference(it) => it.span(), + Self::QualifiedName(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSImportType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSImportAttributes<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSImportAttribute<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSImportAttributeName<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::StringLiteral(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSFunctionType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSConstructorType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSMappedType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTemplateLiteralType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSAsExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSSatisfiesExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSTypeAssertion<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSImportEqualsDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSModuleReference<'a> { + fn span(&self) -> Span { + match self { + Self::ExternalModuleReference(it) => it.span(), + Self::IdentifierReference(it) => it.span(), + Self::QualifiedName(it) => it.span(), + } + } +} + +impl<'a> GetSpan for TSExternalModuleReference<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSNonNullExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for Decorator<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSExportAssignment<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSNamespaceExportDeclaration<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for TSInstantiationExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSDocNullableType<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl GetSpan for JSDocUnknownType { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXOpeningElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXClosingElement<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXFragment<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXElementName<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::NamespacedName(it) => it.span(), + Self::MemberExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXNamespacedName<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXMemberExpression<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXMemberExpressionObject<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::MemberExpression(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXExpressionContainer<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXExpression<'a> { + fn span(&self) -> Span { + match self { + Self::EmptyExpression(it) => it.span(), + Self::BooleanLiteral(it) => it.span(), + Self::NullLiteral(it) => it.span(), + Self::NumericLiteral(it) => it.span(), + Self::BigIntLiteral(it) => it.span(), + Self::RegExpLiteral(it) => it.span(), + Self::StringLiteral(it) => it.span(), + Self::TemplateLiteral(it) => it.span(), + Self::Identifier(it) => it.span(), + Self::MetaProperty(it) => it.span(), + Self::Super(it) => it.span(), + Self::ArrayExpression(it) => it.span(), + Self::ArrowFunctionExpression(it) => it.span(), + Self::AssignmentExpression(it) => it.span(), + Self::AwaitExpression(it) => it.span(), + Self::BinaryExpression(it) => it.span(), + Self::CallExpression(it) => it.span(), + Self::ChainExpression(it) => it.span(), + Self::ClassExpression(it) => it.span(), + Self::ConditionalExpression(it) => it.span(), + Self::FunctionExpression(it) => it.span(), + Self::ImportExpression(it) => it.span(), + Self::LogicalExpression(it) => it.span(), + Self::NewExpression(it) => it.span(), + Self::ObjectExpression(it) => it.span(), + Self::ParenthesizedExpression(it) => it.span(), + Self::SequenceExpression(it) => it.span(), + Self::TaggedTemplateExpression(it) => it.span(), + Self::ThisExpression(it) => it.span(), + Self::UnaryExpression(it) => it.span(), + Self::UpdateExpression(it) => it.span(), + Self::YieldExpression(it) => it.span(), + Self::PrivateInExpression(it) => it.span(), + Self::JSXElement(it) => it.span(), + Self::JSXFragment(it) => it.span(), + Self::TSAsExpression(it) => it.span(), + Self::TSSatisfiesExpression(it) => it.span(), + Self::TSTypeAssertion(it) => it.span(), + Self::TSNonNullExpression(it) => it.span(), + Self::TSInstantiationExpression(it) => it.span(), + Self::ComputedMemberExpression(it) => it.span(), + Self::StaticMemberExpression(it) => it.span(), + Self::PrivateFieldExpression(it) => it.span(), + } + } +} + +impl GetSpan for JSXEmptyExpression { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXAttributeItem<'a> { + fn span(&self) -> Span { + match self { + Self::Attribute(it) => it.span(), + Self::SpreadAttribute(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXAttribute<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXSpreadAttribute<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXAttributeName<'a> { + fn span(&self) -> Span { + match self { + Self::Identifier(it) => it.span(), + Self::NamespacedName(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXAttributeValue<'a> { + fn span(&self) -> Span { + match self { + Self::StringLiteral(it) => it.span(), + Self::ExpressionContainer(it) => it.span(), + Self::Element(it) => it.span(), + Self::Fragment(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXIdentifier<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXChild<'a> { + fn span(&self) -> Span { + match self { + Self::Text(it) => it.span(), + Self::Element(it) => it.span(), + Self::Fragment(it) => it.span(), + Self::ExpressionContainer(it) => it.span(), + Self::Spread(it) => it.span(), + } + } +} + +impl<'a> GetSpan for JSXSpreadChild<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for JSXText<'a> { + #[inline] + fn span(&self) -> Span { + self.span + } +} + +impl<'a> GetSpan for BindingPattern<'a> { + fn span(&self) -> Span { + self.kind.span() + } +} diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index dc77219b1eeac..95f905f77fa98 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -15,13 +15,19 @@ mod serialize; pub mod ast; mod ast_builder; mod ast_impl; -mod ast_kind; +mod ast_kind_impl; pub mod precedence; -mod span; pub mod syntax_directed_operations; mod trivia; pub mod visit; +mod generated { + pub mod ast_kind; + pub mod span; +} + +pub use generated::ast_kind; + pub use num_bigint::BigUint; pub use crate::{ diff --git a/crates/oxc_ast/src/span.rs b/crates/oxc_ast/src/span.rs deleted file mode 100644 index ac9cef1c5b2e3..0000000000000 --- a/crates/oxc_ast/src/span.rs +++ /dev/null @@ -1,747 +0,0 @@ -use oxc_span::{GetSpan, Span}; - -use crate::ast::*; - -impl<'a> GetSpan for Statement<'a> { - fn span(&self) -> Span { - match self { - Self::BlockStatement(stmt) => stmt.span, - Self::BreakStatement(stmt) => stmt.span, - Self::ContinueStatement(stmt) => stmt.span, - Self::DebuggerStatement(stmt) => stmt.span, - Self::DoWhileStatement(stmt) => stmt.span, - Self::EmptyStatement(stmt) => stmt.span, - Self::ExpressionStatement(stmt) => stmt.span, - Self::ForInStatement(stmt) => stmt.span, - Self::ForOfStatement(stmt) => stmt.span, - Self::ForStatement(stmt) => stmt.span, - Self::IfStatement(stmt) => stmt.span, - Self::LabeledStatement(stmt) => stmt.span, - Self::ReturnStatement(stmt) => stmt.span, - Self::SwitchStatement(stmt) => stmt.span, - Self::ThrowStatement(stmt) => stmt.span, - Self::TryStatement(stmt) => stmt.span, - Self::WhileStatement(stmt) => stmt.span, - Self::WithStatement(stmt) => stmt.span, - // `ModuleDeclaration` - Self::ImportDeclaration(decl) => decl.span, - Self::ExportAllDeclaration(decl) => decl.span, - Self::ExportDefaultDeclaration(decl) => decl.span, - Self::ExportNamedDeclaration(decl) => decl.span, - Self::TSExportAssignment(decl) => decl.span, - Self::TSNamespaceExportDeclaration(decl) => decl.span, - // `Declaration` - Self::VariableDeclaration(decl) => decl.span, - Self::FunctionDeclaration(decl) => decl.span, - Self::ClassDeclaration(decl) => decl.span, - Self::UsingDeclaration(decl) => decl.span, - Self::TSTypeAliasDeclaration(decl) => decl.span, - Self::TSInterfaceDeclaration(decl) => decl.span, - Self::TSEnumDeclaration(decl) => decl.span, - Self::TSModuleDeclaration(decl) => decl.span, - Self::TSImportEqualsDeclaration(decl) => decl.span, - } - } -} - -impl<'a> GetSpan for Expression<'a> { - fn span(&self) -> Span { - match self { - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - // `MemberExpression` - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for BindingPatternKind<'a> { - fn span(&self) -> Span { - match self { - Self::BindingIdentifier(ident) => ident.span, - Self::ObjectPattern(pat) => pat.span, - Self::ArrayPattern(pat) => pat.span, - Self::AssignmentPattern(pat) => pat.span, - } - } -} - -impl<'a> GetSpan for BindingPattern<'a> { - fn span(&self) -> Span { - match &self.kind { - BindingPatternKind::BindingIdentifier(ident) => ident.span, - BindingPatternKind::ObjectPattern(pat) => pat.span, - BindingPatternKind::ArrayPattern(pat) => pat.span, - BindingPatternKind::AssignmentPattern(pat) => pat.span, - } - } -} - -impl GetSpan for BindingProperty<'_> { - fn span(&self) -> Span { - self.span - } -} - -impl<'a> GetSpan for ClassElement<'a> { - fn span(&self) -> Span { - match self { - Self::StaticBlock(block) => block.span, - Self::MethodDefinition(def) => def.span, - Self::PropertyDefinition(def) => def.span, - Self::AccessorProperty(def) => def.span, - Self::TSIndexSignature(sig) => sig.span, - } - } -} - -impl<'a> GetSpan for PropertyKey<'a> { - fn span(&self) -> Span { - match self { - Self::StaticIdentifier(ident) => ident.span, - Self::PrivateIdentifier(ident) => ident.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for MemberExpression<'a> { - fn span(&self) -> Span { - match self { - Self::ComputedMemberExpression(expr) => expr.span, - Self::StaticMemberExpression(expr) => expr.span, - Self::PrivateFieldExpression(expr) => expr.span, - } - } -} - -impl<'a> GetSpan for ImportAttributeKey<'a> { - fn span(&self) -> Span { - match self { - Self::Identifier(identifier) => identifier.span, - Self::StringLiteral(literal) => literal.span, - } - } -} - -impl<'a> GetSpan for ModuleExportName<'a> { - fn span(&self) -> Span { - match self { - Self::IdentifierName(identifier) => identifier.span, - Self::IdentifierReference(identifier) => identifier.span, - Self::StringLiteral(literal) => literal.span, - } - } -} - -impl<'a> GetSpan for ModuleDeclaration<'a> { - fn span(&self) -> Span { - match self { - Self::ImportDeclaration(decl) => decl.span, - Self::ExportAllDeclaration(decl) => decl.span, - Self::ExportDefaultDeclaration(decl) => decl.span, - Self::ExportNamedDeclaration(decl) => decl.span, - Self::TSExportAssignment(decl) => decl.span, - Self::TSNamespaceExportDeclaration(decl) => decl.span, - } - } -} - -impl<'a> GetSpan for Declaration<'a> { - fn span(&self) -> Span { - match self { - Self::VariableDeclaration(decl) => decl.span, - Self::FunctionDeclaration(decl) => decl.span, - Self::UsingDeclaration(decl) => decl.span, - Self::ClassDeclaration(decl) => decl.span, - Self::TSTypeAliasDeclaration(decl) => decl.span, - Self::TSInterfaceDeclaration(decl) => decl.span, - Self::TSEnumDeclaration(decl) => decl.span, - Self::TSModuleDeclaration(decl) => decl.span, - Self::TSImportEqualsDeclaration(decl) => decl.span, - } - } -} - -impl<'a> GetSpan for TSModuleDeclarationName<'a> { - fn span(&self) -> Span { - match self { - Self::Identifier(ident) => ident.span, - Self::StringLiteral(lit) => lit.span, - } - } -} - -impl<'a> GetSpan for ObjectPropertyKind<'a> { - fn span(&self) -> Span { - match self { - Self::ObjectProperty(p) => p.span, - Self::SpreadProperty(p) => p.span, - } - } -} - -impl<'a> GetSpan for AssignmentTarget<'a> { - fn span(&self) -> Span { - match self { - // `SimpleAssignmentTarget` - Self::AssignmentTargetIdentifier(ident) => ident.span, - Self::TSAsExpression(expr) => expr.span, - Self::TSSatisfiesExpression(expr) => expr.span, - Self::TSNonNullExpression(expr) => expr.span, - Self::TSTypeAssertion(expr) => expr.span, - Self::TSInstantiationExpression(expr) => expr.span, - // `AssignmentTargetPattern` - Self::ComputedMemberExpression(expr) => expr.span, - Self::StaticMemberExpression(expr) => expr.span, - Self::PrivateFieldExpression(expr) => expr.span, - Self::ArrayAssignmentTarget(pat) => pat.span, - Self::ObjectAssignmentTarget(pat) => pat.span, - } - } -} - -impl<'a> GetSpan for AssignmentTargetProperty<'a> { - fn span(&self) -> Span { - match self { - Self::AssignmentTargetPropertyIdentifier(identifier) => identifier.span, - Self::AssignmentTargetPropertyProperty(literal) => literal.span, - } - } -} - -impl<'a> GetSpan for Argument<'a> { - fn span(&self) -> Span { - match self { - Self::SpreadElement(e) => e.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for ArrayExpression<'a> { - fn span(&self) -> Span { - self.span - } -} - -impl<'a> GetSpan for ArrayExpressionElement<'a> { - fn span(&self) -> Span { - match self { - Self::SpreadElement(e) => e.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - - Self::Elision(elision) => elision.span, - } - } -} - -impl<'a> GetSpan for ForStatementInit<'a> { - fn span(&self) -> Span { - match self { - Self::VariableDeclaration(x) => x.span, - Self::UsingDeclaration(x) => x.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for ForStatementLeft<'a> { - fn span(&self) -> Span { - match self { - Self::VariableDeclaration(x) => x.span, - // `AssignmentTarget` - Self::AssignmentTargetIdentifier(x) => x.span, - Self::ComputedMemberExpression(x) => x.span, - Self::StaticMemberExpression(x) => x.span, - Self::PrivateFieldExpression(x) => x.span, - Self::TSAsExpression(x) => x.span, - Self::TSSatisfiesExpression(x) => x.span, - Self::TSNonNullExpression(x) => x.span, - Self::TSTypeAssertion(x) => x.span, - Self::TSInstantiationExpression(x) => x.span, - Self::ArrayAssignmentTarget(x) => x.span, - Self::ObjectAssignmentTarget(x) => x.span, - Self::UsingDeclaration(x) => x.span, - } - } -} - -impl<'a> GetSpan for SimpleAssignmentTarget<'a> { - fn span(&self) -> Span { - match self { - Self::AssignmentTargetIdentifier(ident) => ident.span, - Self::TSAsExpression(expr) => expr.span, - Self::TSSatisfiesExpression(expr) => expr.span, - Self::TSNonNullExpression(expr) => expr.span, - Self::TSTypeAssertion(expr) => expr.span, - Self::TSInstantiationExpression(expr) => expr.span, - // `MemberExpression` - Self::ComputedMemberExpression(expr) => expr.span, - Self::StaticMemberExpression(expr) => expr.span, - Self::PrivateFieldExpression(expr) => expr.span, - } - } -} - -impl<'a> GetSpan for JSXElementName<'a> { - fn span(&self) -> Span { - match self { - Self::Identifier(ident) => ident.span, - Self::NamespacedName(name) => name.span, - Self::MemberExpression(expr) => expr.span, - } - } -} - -impl<'a> GetSpan for JSXElement<'a> { - fn span(&self) -> Span { - self.span - } -} - -impl<'a> GetSpan for TSSignature<'a> { - fn span(&self) -> Span { - match self { - Self::TSIndexSignature(sig) => sig.span, - Self::TSPropertySignature(sig) => sig.span, - Self::TSCallSignatureDeclaration(decl) => decl.span, - Self::TSConstructSignatureDeclaration(decl) => decl.span, - Self::TSMethodSignature(sig) => sig.span, - } - } -} - -impl<'a> GetSpan for TSType<'a> { - fn span(&self) -> Span { - match self { - Self::TSConditionalType(t) => t.span, - Self::TSFunctionType(t) => t.span, - Self::TSLiteralType(t) => t.span, - Self::TSTypeReference(t) => t.span, - Self::TSTypeQuery(t) => t.span, - Self::TSUnionType(t) => t.span, - Self::TSTupleType(t) => t.span, - Self::TSArrayType(t) => t.span, - Self::TSIntersectionType(t) => t.span, - Self::TSMappedType(t) => t.span, - Self::TSNamedTupleMember(t) => t.span, - Self::TSInferType(t) => t.span, - Self::TSConstructorType(t) => t.span, - Self::TSIndexedAccessType(t) => t.span, - Self::TSTypeOperatorType(t) => t.span, - Self::TSImportType(t) => t.span, - Self::TSQualifiedName(t) => t.span, - Self::TSTypePredicate(t) => t.span, - Self::TSTypeLiteral(t) => t.span, - Self::TSTemplateLiteralType(t) => t.span, - Self::TSAnyKeyword(t) => t.span, - Self::TSUnknownKeyword(t) => t.span, - Self::TSUndefinedKeyword(t) => t.span, - Self::TSNullKeyword(t) => t.span, - Self::TSNumberKeyword(t) => t.span, - Self::TSStringKeyword(t) => t.span, - Self::TSNeverKeyword(t) => t.span, - Self::TSBooleanKeyword(t) => t.span, - Self::TSIntrinsicKeyword(t) => t.span, - Self::TSSymbolKeyword(t) => t.span, - Self::TSBigIntKeyword(t) => t.span, - Self::TSThisType(t) => t.span, - Self::TSVoidKeyword(t) => t.span, - Self::TSObjectKeyword(t) => t.span, - Self::JSDocNullableType(t) => t.span, - Self::JSDocUnknownType(t) => t.span, - } - } -} - -impl<'a> GetSpan for ExportDefaultDeclarationKind<'a> { - fn span(&self) -> Span { - match self { - Self::ClassDeclaration(x) => x.span, - Self::FunctionDeclaration(x) => x.span, - Self::TSInterfaceDeclaration(x) => x.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for ImportDeclarationSpecifier<'a> { - fn span(&self) -> Span { - match self { - Self::ImportSpecifier(specifier) => specifier.span, - Self::ImportDefaultSpecifier(specifier) => specifier.span, - Self::ImportNamespaceSpecifier(specifier) => specifier.span, - } - } -} - -impl<'a> GetSpan for JSXChild<'a> { - fn span(&self) -> Span { - match self { - Self::Element(element) => element.span, - Self::ExpressionContainer(container) => container.span, - Self::Text(text) => text.span, - Self::Fragment(fragment) => fragment.span, - Self::Spread(spread) => spread.span, - } - } -} - -impl<'a> GetSpan for AssignmentTargetPattern<'a> { - fn span(&self) -> Span { - match &self { - Self::ArrayAssignmentTarget(x) => x.span, - Self::ObjectAssignmentTarget(x) => x.span, - } - } -} - -impl<'a> GetSpan for JSXAttributeItem<'a> { - fn span(&self) -> Span { - match &self { - JSXAttributeItem::Attribute(attr) => attr.span, - JSXAttributeItem::SpreadAttribute(attr) => attr.span, - } - } -} - -impl<'a> GetSpan for JSXExpression<'a> { - fn span(&self) -> Span { - match &self { - Self::EmptyExpression(empty_expr) => empty_expr.span, - // `Expression` - Self::BooleanLiteral(e) => e.span, - Self::NullLiteral(e) => e.span, - Self::NumericLiteral(e) => e.span, - Self::BigintLiteral(e) => e.span, - Self::RegExpLiteral(e) => e.span, - Self::StringLiteral(e) => e.span, - Self::TemplateLiteral(e) => e.span, - Self::Identifier(e) => e.span, - Self::MetaProperty(e) => e.span, - Self::Super(e) => e.span, - Self::ArrayExpression(e) => e.span, - Self::ArrowFunctionExpression(e) => e.span, - Self::AssignmentExpression(e) => e.span, - Self::AwaitExpression(e) => e.span, - Self::BinaryExpression(e) => e.span, - Self::CallExpression(e) => e.span, - Self::ChainExpression(e) => e.span, - Self::ClassExpression(e) => e.span, - Self::ConditionalExpression(e) => e.span, - Self::FunctionExpression(e) => e.span, - Self::ImportExpression(e) => e.span, - Self::LogicalExpression(e) => e.span, - Self::NewExpression(e) => e.span, - Self::ObjectExpression(e) => e.span, - Self::ParenthesizedExpression(e) => e.span, - Self::SequenceExpression(e) => e.span, - Self::TaggedTemplateExpression(e) => e.span, - Self::ThisExpression(e) => e.span, - Self::UnaryExpression(e) => e.span, - Self::UpdateExpression(e) => e.span, - Self::YieldExpression(e) => e.span, - Self::PrivateInExpression(e) => e.span, - Self::JSXElement(e) => e.span, - Self::JSXFragment(e) => e.span, - Self::TSAsExpression(e) => e.span, - Self::TSSatisfiesExpression(e) => e.span, - Self::TSTypeAssertion(e) => e.span, - Self::TSNonNullExpression(e) => e.span, - Self::TSInstantiationExpression(e) => e.span, - Self::ComputedMemberExpression(e) => e.span, - Self::StaticMemberExpression(e) => e.span, - Self::PrivateFieldExpression(e) => e.span, - } - } -} - -impl<'a> GetSpan for JSXAttributeName<'a> { - fn span(&self) -> Span { - match &self { - JSXAttributeName::Identifier(ident) => ident.span, - JSXAttributeName::NamespacedName(namespaced_name) => namespaced_name.span, - } - } -} - -impl<'a> GetSpan for JSXAttributeValue<'a> { - fn span(&self) -> Span { - match &self { - JSXAttributeValue::StringLiteral(literal) => literal.span, - JSXAttributeValue::ExpressionContainer(container) => container.span, - JSXAttributeValue::Fragment(fragment) => fragment.span, - JSXAttributeValue::Element(element) => element.span, - } - } -} - -impl<'a> GetSpan for JSXMemberExpressionObject<'a> { - fn span(&self) -> Span { - match &self { - JSXMemberExpressionObject::Identifier(ident) => ident.span, - JSXMemberExpressionObject::MemberExpression(expr) => expr.span, - } - } -} - -impl<'a> GetSpan for TSEnumMemberName<'a> { - fn span(&self) -> Span { - match self { - TSEnumMemberName::StaticIdentifier(ident) => ident.span, - TSEnumMemberName::StaticStringLiteral(literal) => literal.span, - TSEnumMemberName::StaticNumericLiteral(literal) => literal.span, - expr @ match_expression!(TSEnumMemberName) => expr.to_expression().span(), - } - } -} diff --git a/crates/oxc_ast/src/visit/visit.rs b/crates/oxc_ast/src/visit/visit.rs index 022a7a887000e..532357f738cbc 100644 --- a/crates/oxc_ast/src/visit/visit.rs +++ b/crates/oxc_ast/src/visit/visit.rs @@ -1472,7 +1472,7 @@ pub mod walk { pub fn walk_expression<'a, V: Visit<'a>>(visitor: &mut V, expr: &Expression<'a>) { match expr { - Expression::BigintLiteral(lit) => visitor.visit_bigint_literal(lit), + Expression::BigIntLiteral(lit) => visitor.visit_bigint_literal(lit), Expression::BooleanLiteral(lit) => visitor.visit_boolean_literal(lit), Expression::NullLiteral(lit) => visitor.visit_null_literal(lit), Expression::NumericLiteral(lit) => visitor.visit_number_literal(lit), @@ -2316,7 +2316,7 @@ pub mod walk { } pub fn walk_bigint_literal<'a, V: Visit<'a>>(visitor: &mut V, lit: &BigIntLiteral<'a>) { - let kind = AstKind::BigintLiteral(visitor.alloc(lit)); + let kind = AstKind::BigIntLiteral(visitor.alloc(lit)); visitor.enter_node(kind); visitor.leave_node(kind); } @@ -3006,7 +3006,7 @@ pub mod walk { let kind = AstKind::TSLiteralType(visitor.alloc(ty)); visitor.enter_node(kind); match &ty.literal { - TSLiteral::BigintLiteral(lit) => visitor.visit_bigint_literal(lit), + TSLiteral::BigIntLiteral(lit) => visitor.visit_bigint_literal(lit), TSLiteral::BooleanLiteral(lit) => visitor.visit_boolean_literal(lit), TSLiteral::NullLiteral(lit) => visitor.visit_null_literal(lit), TSLiteral::NumericLiteral(lit) => visitor.visit_number_literal(lit), diff --git a/crates/oxc_ast/src/visit/visit_mut.rs b/crates/oxc_ast/src/visit/visit_mut.rs index e39c0aa5e6b3c..507af2405ced5 100644 --- a/crates/oxc_ast/src/visit/visit_mut.rs +++ b/crates/oxc_ast/src/visit/visit_mut.rs @@ -1459,7 +1459,7 @@ pub mod walk_mut { pub fn walk_expression_mut<'a, V: VisitMut<'a>>(visitor: &mut V, expr: &mut Expression<'a>) { match expr { - Expression::BigintLiteral(lit) => visitor.visit_bigint_literal(lit), + Expression::BigIntLiteral(lit) => visitor.visit_bigint_literal(lit), Expression::BooleanLiteral(lit) => visitor.visit_boolean_literal(lit), Expression::NullLiteral(lit) => visitor.visit_null_literal(lit), Expression::NumericLiteral(lit) => visitor.visit_number_literal(lit), @@ -2402,7 +2402,7 @@ pub mod walk_mut { visitor: &mut V, _lit: &mut BigIntLiteral<'a>, ) { - let kind = AstType::BigintLiteral; + let kind = AstType::BigIntLiteral; visitor.enter_node(kind); visitor.leave_node(kind); } @@ -3078,7 +3078,7 @@ pub mod walk_mut { let kind = AstType::TSLiteralType; visitor.enter_node(kind); match &mut ty.literal { - TSLiteral::BigintLiteral(lit) => visitor.visit_bigint_literal(lit), + TSLiteral::BigIntLiteral(lit) => visitor.visit_bigint_literal(lit), TSLiteral::BooleanLiteral(lit) => visitor.visit_boolean_literal(lit), TSLiteral::NullLiteral(lit) => visitor.visit_null_literal(lit), TSLiteral::NumericLiteral(lit) => visitor.visit_number_literal(lit), diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index 92efceb9e3ca0..37154f9e53877 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -1,8 +1,28 @@ use proc_macro::TokenStream; +use std::str::FromStr; /// Attach to AST node type (struct or enum), to signal to codegen to create visitor for this type. -/// Macro itself does nothing - just passes through the token stream unchanged. +/// +/// Macro does not generate any code - it's purely a means to communicate information to the codegen. +/// +/// Only thing macro does is add `#[derive(VisitedNode)]` to the item. +/// Deriving `VisitedNode` does nothing, but supports the `#[scope]` attr on struct fields. +/// This is a workaround for Rust not supporting helper attributes for `proc_macro_attribute` macros, +/// so we need to use a derive macro to get that support. +/// +/// Use native Rust `TokenStream`, to avoid dependency on slow-compiling crates like `syn` and `quote`. #[proc_macro_attribute] +#[allow(clippy::missing_panics_doc)] pub fn visited_node(_args: TokenStream, input: TokenStream) -> TokenStream { - input + let mut stream = TokenStream::from_str("#[derive(::oxc_ast_macros::VisitedNode)]").unwrap(); + stream.extend(input); + stream +} + +/// Dummy derive macro for a non-existent trait `VisitedNode`. +/// +/// Does not generate any code, only purpose is to allow using `#[scope]` attr in the type def. +#[proc_macro_derive(VisitedNode, attributes(scope))] +pub fn visited_node_derive(_item: TokenStream) -> TokenStream { + TokenStream::new() } diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 08536c05ea5b8..2730be555263b 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1020,7 +1020,7 @@ impl<'a, const MINIFY: bool> GenExpr for Expression<'a> { Self::BooleanLiteral(lit) => lit.gen(p, ctx), Self::NullLiteral(lit) => lit.gen(p, ctx), Self::NumericLiteral(lit) => lit.gen(p, ctx), - Self::BigintLiteral(lit) => lit.gen(p, ctx), + Self::BigIntLiteral(lit) => lit.gen(p, ctx), Self::RegExpLiteral(lit) => lit.gen(p, ctx), Self::StringLiteral(lit) => lit.gen(p, ctx), Self::Identifier(ident) => ident.gen(p, ctx), @@ -2958,7 +2958,7 @@ impl<'a, const MINIFY: bool> Gen for TSLiteral<'a> { Self::BooleanLiteral(decl) => decl.gen(p, ctx), Self::NullLiteral(decl) => decl.gen(p, ctx), Self::NumericLiteral(decl) => decl.gen(p, ctx), - Self::BigintLiteral(decl) => decl.gen(p, ctx), + Self::BigIntLiteral(decl) => decl.gen(p, ctx), Self::RegExpLiteral(decl) => decl.gen(p, ctx), Self::StringLiteral(decl) => decl.gen(p, ctx), Self::TemplateLiteral(decl) => decl.gen(p, ctx), diff --git a/crates/oxc_diagnostics/src/graphic_reporter.rs b/crates/oxc_diagnostics/src/graphic_reporter.rs index 8a3c3e5a7b986..d3bdee7827155 100644 --- a/crates/oxc_diagnostics/src/graphic_reporter.rs +++ b/crates/oxc_diagnostics/src/graphic_reporter.rs @@ -1122,9 +1122,9 @@ impl GraphicalReportHandler { let mut column = context_data.column(); let mut offset = context_data.span().offset(); let mut line_offset = offset; + let mut line_str = String::with_capacity(context.len()); + let mut lines = Vec::with_capacity(1); let mut iter = context.chars().peekable(); - let mut line_str = String::new(); - let mut lines = Vec::new(); while let Some(char) = iter.next() { offset += char.len_utf8(); let mut at_end_of_file = false; diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index 36168c2608e32..b709f22dd9167 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -17,13 +17,13 @@ impl<'a> IsolatedDeclarations<'a> { match key { PropertyKey::StringLiteral(_) | PropertyKey::NumericLiteral(_) - | PropertyKey::BigintLiteral(_) => true, + | PropertyKey::BigIntLiteral(_) => true, PropertyKey::TemplateLiteral(l) => l.expressions.is_empty(), PropertyKey::UnaryExpression(expr) => { expr.operator.is_arithmetic() && matches!( expr.argument, - Expression::NumericLiteral(_) | Expression::BigintLiteral(_) + Expression::NumericLiteral(_) | Expression::BigIntLiteral(_) ) } _ => false, @@ -505,7 +505,7 @@ impl<'a> IsolatedDeclarations<'a> { kind: BindingPatternKind<'a>, type_annotation: Option>>, ) -> Box<'a, FormalParameters<'a>> { - let pattern = BindingPattern { span: SPAN, kind, type_annotation, optional: false }; + let pattern = BindingPattern { kind, type_annotation, optional: false }; let parameter = self.ast.formal_parameter(SPAN, pattern, None, false, false, self.ast.new_vec()); let items = self.ast.new_vec_single(parameter); diff --git a/crates/oxc_isolated_declarations/src/declaration.rs b/crates/oxc_isolated_declarations/src/declaration.rs index 6906262898f45..cfc2291254011 100644 --- a/crates/oxc_isolated_declarations/src/declaration.rs +++ b/crates/oxc_isolated_declarations/src/declaration.rs @@ -95,7 +95,6 @@ impl<'a> IsolatedDeclarations<'a> { || self.ast.copy(&decl.id), |ts_type| { self.ast.binding_pattern( - SPAN, self.ast.copy(&decl.id.kind), Some(self.ast.ts_type_annotation(SPAN, ts_type)), decl.id.optional, diff --git a/crates/oxc_isolated_declarations/src/function.rs b/crates/oxc_isolated_declarations/src/function.rs index 6d7b141262835..12c7278f6b992 100644 --- a/crates/oxc_isolated_declarations/src/function.rs +++ b/crates/oxc_isolated_declarations/src/function.rs @@ -99,7 +99,6 @@ impl<'a> IsolatedDeclarations<'a> { }); pattern = self.ast.binding_pattern( - SPAN, self.ast.copy(&pattern.kind), type_annotation, // if it's assignment pattern, it's optional diff --git a/crates/oxc_isolated_declarations/src/inferrer.rs b/crates/oxc_isolated_declarations/src/inferrer.rs index b631ed334fcaa..0bab7117ee695 100644 --- a/crates/oxc_isolated_declarations/src/inferrer.rs +++ b/crates/oxc_isolated_declarations/src/inferrer.rs @@ -19,7 +19,7 @@ impl<'a> IsolatedDeclarations<'a> { Expression::BooleanLiteral(_) => Some(self.ast.ts_boolean_keyword(SPAN)), Expression::NullLiteral(_) => Some(self.ast.ts_null_keyword(SPAN)), Expression::NumericLiteral(_) => Some(self.ast.ts_number_keyword(SPAN)), - Expression::BigintLiteral(_) => Some(self.ast.ts_bigint_keyword(SPAN)), + Expression::BigIntLiteral(_) => Some(self.ast.ts_bigint_keyword(SPAN)), Expression::StringLiteral(_) => Some(self.ast.ts_string_keyword(SPAN)), Expression::TemplateLiteral(lit) => { if lit.expressions.is_empty() { @@ -139,7 +139,7 @@ impl<'a> IsolatedDeclarations<'a> { pub fn is_need_to_infer_type_from_expression(expr: &Expression) -> bool { match expr { Expression::NumericLiteral(_) - | Expression::BigintLiteral(_) + | Expression::BigIntLiteral(_) | Expression::StringLiteral(_) => false, Expression::TemplateLiteral(lit) => !lit.expressions.is_empty(), _ => true, diff --git a/crates/oxc_isolated_declarations/src/module.rs b/crates/oxc_isolated_declarations/src/module.rs index c0ffde42a16c9..04ca3cd9034f8 100644 --- a/crates/oxc_isolated_declarations/src/module.rs +++ b/crates/oxc_isolated_declarations/src/module.rs @@ -65,8 +65,7 @@ impl<'a> IsolatedDeclarations<'a> { self.error(default_export_inferred(expr.span())); } - let id = - BindingPattern { span: SPAN, kind: id, type_annotation, optional: false }; + let id = BindingPattern { kind: id, type_annotation, optional: false }; let declarations = self .ast .new_vec_single(self.ast.variable_declarator(SPAN, kind, id, None, true)); diff --git a/crates/oxc_isolated_declarations/src/types.rs b/crates/oxc_isolated_declarations/src/types.rs index b8fd4a294f014..ee9cc9860a08d 100644 --- a/crates/oxc_isolated_declarations/src/types.rs +++ b/crates/oxc_isolated_declarations/src/types.rs @@ -178,8 +178,8 @@ impl<'a> IsolatedDeclarations<'a> { Expression::NumericLiteral(lit) => { Some(self.ast.ts_literal_type(SPAN, TSLiteral::NumericLiteral(self.ast.copy(lit)))) } - Expression::BigintLiteral(lit) => { - Some(self.ast.ts_literal_type(SPAN, TSLiteral::BigintLiteral(self.ast.copy(lit)))) + Expression::BigIntLiteral(lit) => { + Some(self.ast.ts_literal_type(SPAN, TSLiteral::BigIntLiteral(self.ast.copy(lit)))) } Expression::StringLiteral(lit) => { Some(self.ast.ts_literal_type(SPAN, TSLiteral::StringLiteral(self.ast.copy(lit)))) diff --git a/crates/oxc_linter/fixtures/eslint_config_vitest_replace.json b/crates/oxc_linter/fixtures/eslint_config_vitest_replace.json new file mode 100644 index 0000000000000..9db9a461312ee --- /dev/null +++ b/crates/oxc_linter/fixtures/eslint_config_vitest_replace.json @@ -0,0 +1,5 @@ +{ + "rules": { + "vitest/no-disabled-tests": "error" + } +} diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index ca7dfd9825b48..db9580fee54b7 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -16,7 +16,9 @@ pub use self::{ rules::OxlintRules, settings::{jsdoc::JSDocPluginSettings, OxlintSettings}, }; -use crate::{rules::RuleEnum, AllowWarnDeny, RuleWithSeverity}; +use crate::{ + rules::RuleEnum, utils::is_jest_rule_adapted_to_vitest, AllowWarnDeny, RuleWithSeverity, +}; /// Oxlint Configuration File /// @@ -113,8 +115,10 @@ impl OxlintConfig { 0 => unreachable!(), 1 => { let rule_config = &rule_configs[0]; - let rule_name = &rule_config.rule_name; - let plugin_name = &rule_config.plugin_name; + let (rule_name, plugin_name) = transform_rule_and_plugin_name( + &rule_config.rule_name, + &rule_config.plugin_name, + ); let severity = rule_config.severity; match severity { AllowWarnDeny::Warn | AllowWarnDeny::Deny => { @@ -168,12 +172,26 @@ impl OxlintConfig { } } +fn transform_rule_and_plugin_name<'a>( + rule_name: &'a str, + plugin_name: &'a str, +) -> (&'a str, &'a str) { + if plugin_name == "vitest" && is_jest_rule_adapted_to_vitest(rule_name) { + return (rule_name, "jest"); + } + + (rule_name, plugin_name) +} + #[cfg(test)] mod test { use std::env; + use rustc_hash::FxHashSet; use serde::Deserialize; + use crate::rules::RULES; + use super::OxlintConfig; #[test] @@ -221,4 +239,17 @@ mod test { assert_eq!(env.iter().count(), 1); assert!(globals.is_enabled("foo")); } + + #[test] + fn test_vitest_rule_replace() { + let fixture_path: std::path::PathBuf = + env::current_dir().unwrap().join("fixtures/eslint_config_vitest_replace.json"); + let config = OxlintConfig::from_file(&fixture_path).unwrap(); + let mut set = FxHashSet::default(); + config.override_rules(&mut set, &RULES); + + let rule = set.into_iter().next().unwrap(); + assert_eq!(rule.name(), "no-disabled-tests"); + assert_eq!(rule.plugin_name(), "jest"); + } } diff --git a/crates/oxc_linter/src/context.rs b/crates/oxc_linter/src/context.rs index 668522e885b48..f30b9d6fdde75 100644 --- a/crates/oxc_linter/src/context.rs +++ b/crates/oxc_linter/src/context.rs @@ -7,6 +7,7 @@ use oxc_span::{SourceType, Span}; use oxc_syntax::module_record::ModuleRecord; use crate::{ + config::OxlintRules, disable_directives::{DisableDirectives, DisableDirectivesBuilder}, fixer::{Fix, Message, RuleFixer}, javascript_globals::GLOBALS, @@ -131,6 +132,10 @@ impl<'a> LintContext<'a> { &self.eslint_config.env } + pub fn rules(&self) -> &OxlintRules { + &self.eslint_config.rules + } + pub fn env_contains_var(&self, var: &str) -> bool { for env in self.env().iter() { let env = GLOBALS.get(env).unwrap_or(&GLOBALS["builtin"]); diff --git a/crates/oxc_linter/src/options.rs b/crates/oxc_linter/src/options.rs index 138236cbc0eac..258ec0d2167df 100644 --- a/crates/oxc_linter/src/options.rs +++ b/crates/oxc_linter/src/options.rs @@ -4,7 +4,10 @@ use oxc_diagnostics::{Error, OxcDiagnostic, Severity}; use rustc_hash::FxHashSet; use serde_json::{Number, Value}; -use crate::{config::OxlintConfig, rules::RULES, RuleCategory, RuleEnum, RuleWithSeverity}; +use crate::{ + config::OxlintConfig, rules::RULES, utils::is_jest_rule_adapted_to_vitest, RuleCategory, + RuleEnum, RuleWithSeverity, +}; #[derive(Debug)] pub struct LintOptions { @@ -21,6 +24,7 @@ pub struct LintOptions { pub import_plugin: bool, pub jsdoc_plugin: bool, pub jest_plugin: bool, + pub vitest_plugin: bool, pub jsx_a11y_plugin: bool, pub nextjs_plugin: bool, pub react_perf_plugin: bool, @@ -39,6 +43,7 @@ impl Default for LintOptions { import_plugin: false, jsdoc_plugin: false, jest_plugin: false, + vitest_plugin: false, jsx_a11y_plugin: false, nextjs_plugin: false, react_perf_plugin: false, @@ -109,6 +114,12 @@ impl LintOptions { self } + #[must_use] + pub fn with_vitest_plugin(mut self, yes: bool) -> Self { + self.vitest_plugin = yes; + self + } + #[must_use] pub fn with_jsx_a11y_plugin(mut self, yes: bool) -> Self { self.jsx_a11y_plugin = yes; @@ -277,7 +288,15 @@ impl LintOptions { "typescript" => self.typescript_plugin, "import" => self.import_plugin, "jsdoc" => self.jsdoc_plugin, - "jest" => self.jest_plugin, + "jest" => { + if self.jest_plugin { + return true; + } + if self.vitest_plugin && is_jest_rule_adapted_to_vitest(rule.name()) { + return true; + } + false + } "jsx_a11y" => self.jsx_a11y_plugin, "nextjs" => self.nextjs_plugin, "react_perf" => self.react_perf_plugin, diff --git a/crates/oxc_linter/src/rules/eslint/eqeqeq.rs b/crates/oxc_linter/src/rules/eslint/eqeqeq.rs index d735d91c4a75b..783c7a5d15b93 100644 --- a/crates/oxc_linter/src/rules/eslint/eqeqeq.rs +++ b/crates/oxc_linter/src/rules/eslint/eqeqeq.rs @@ -193,7 +193,7 @@ fn are_literals_and_same_type(left: &Expression, right: &Expression) -> bool { | (Expression::NullLiteral(_), Expression::NullLiteral(_)) | (Expression::StringLiteral(_), Expression::StringLiteral(_)) | (Expression::NumericLiteral(_), Expression::NumericLiteral(_)) - | (Expression::BigintLiteral(_), Expression::BigintLiteral(_)) + | (Expression::BigIntLiteral(_), Expression::BigIntLiteral(_)) | (Expression::RegExpLiteral(_), Expression::RegExpLiteral(_)) | (Expression::TemplateLiteral(_), Expression::TemplateLiteral(_)) ) diff --git a/crates/oxc_linter/src/rules/eslint/no_compare_neg_zero.rs b/crates/oxc_linter/src/rules/eslint/no_compare_neg_zero.rs index eb1b2da3adb1c..5690e7ef198e0 100644 --- a/crates/oxc_linter/src/rules/eslint/no_compare_neg_zero.rs +++ b/crates/oxc_linter/src/rules/eslint/no_compare_neg_zero.rs @@ -63,7 +63,7 @@ fn is_neg_zero(expr: &Expression) -> bool { } match &unary.argument { Expression::NumericLiteral(number) => number.value == 0.0, - Expression::BigintLiteral(bigint) => bigint.is_zero(), + Expression::BigIntLiteral(bigint) => bigint.is_zero(), _ => false, } } diff --git a/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs b/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs index cc92ce62a6848..0ae05ca4addaa 100644 --- a/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs +++ b/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs @@ -7,8 +7,8 @@ use crate::{ context::LintContext, rule::Rule, utils::{ - collect_possible_jest_call_node, parse_general_jest_fn_call, JestFnKind, JestGeneralFnKind, - ParsedGeneralJestFnCall, PossibleJestNode, + collect_possible_jest_call_node, get_test_plugin_name, parse_general_jest_fn_call, + JestFnKind, JestGeneralFnKind, ParsedGeneralJestFnCall, PossibleJestNode, }, }; @@ -48,14 +48,25 @@ declare_oxc_lint!( /// pending(); /// }); /// ``` + /// + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md), + /// to use it, add the following configuration to your `.eslintrc.json`: + /// + /// ```json + /// { + /// "rules": { + /// "vitest/no-disabled-tests": "error" + /// } + /// } + /// ``` NoDisabledTests, correctness ); -fn no_disabled_tests_diagnostic(x0: &str, x1: &str, span2: Span) -> OxcDiagnostic { - OxcDiagnostic::warn(format!("eslint-plugin-jest(no-disabled-tests): {x0:?}")) - .with_help(format!("{x1:?}")) - .with_labels([span2.into()]) +fn no_disabled_tests_diagnostic(x0: &str, x1: &str, x2: &str, span3: Span) -> OxcDiagnostic { + OxcDiagnostic::warn(format!("{x0}(no-disabled-tests): {x1:?}")) + .with_help(format!("{x2:?}")) + .with_labels([span3.into()]) } enum Message { @@ -82,13 +93,19 @@ impl Message { impl Rule for NoDisabledTests { fn run_once(&self, ctx: &LintContext) { + let plugin_name = get_test_plugin_name(ctx); + for possible_jest_node in &collect_possible_jest_call_node(ctx) { - run(possible_jest_node, ctx); + run(possible_jest_node, plugin_name, ctx); } } } -fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) { +fn run<'a>( + possible_jest_node: &PossibleJestNode<'a, '_>, + plugin_name: &str, + ctx: &LintContext<'a>, +) { let node = possible_jest_node.node; if let AstKind::CallExpression(call_expr) = node.kind() { if let Some(jest_fn_call) = parse_general_jest_fn_call(call_expr, possible_jest_node, ctx) { @@ -103,7 +120,12 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) && members.iter().all(|member| member.is_name_unequal("todo")) { let (error, help) = Message::MissingFunction.details(); - ctx.diagnostic(no_disabled_tests_diagnostic(error, help, call_expr.span)); + ctx.diagnostic(no_disabled_tests_diagnostic( + plugin_name, + error, + help, + call_expr.span, + )); return; } @@ -115,7 +137,12 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) } else { Message::DisabledTestWithX.details() }; - ctx.diagnostic(no_disabled_tests_diagnostic(error, help, call_expr.callee.span())); + ctx.diagnostic(no_disabled_tests_diagnostic( + plugin_name, + error, + help, + call_expr.callee.span(), + )); return; } @@ -127,7 +154,12 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) } else { Message::DisabledTestWithSkip.details() }; - ctx.diagnostic(no_disabled_tests_diagnostic(error, help, call_expr.callee.span())); + ctx.diagnostic(no_disabled_tests_diagnostic( + plugin_name, + error, + help, + call_expr.callee.span(), + )); } } else if let Expression::Identifier(ident) = &call_expr.callee { if ident.name.as_str() == "pending" @@ -135,7 +167,12 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) { // `describe('foo', function () { pending() })` let (error, help) = Message::Pending.details(); - ctx.diagnostic(no_disabled_tests_diagnostic(error, help, call_expr.span)); + ctx.diagnostic(no_disabled_tests_diagnostic( + plugin_name, + error, + help, + call_expr.span, + )); } } } @@ -145,7 +182,7 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ("describe('foo', function () {})", None), ("it('foo', function () {})", None), ("describe.only('foo', function () {})", None), @@ -184,7 +221,7 @@ fn test() { ("import { test } from './test-utils'; test('something');", None), ]; - let fail = vec![ + let mut fail = vec![ ("describe.skip('foo', function () {})", None), ("describe.skip.each([1, 2, 3])('%s', (a, b) => {});", None), ("xdescribe.each([1, 2, 3])('%s', (a, b) => {});", None), @@ -213,5 +250,59 @@ fn test() { ("import { test } from '@jest/globals';test('something');", None), ]; - Tester::new(NoDisabledTests::NAME, pass, fail).with_jest_plugin(true).test_and_snapshot(); + let pass_vitest = vec![ + r#"describe("foo", function () {})"#, + r#"it("foo", function () {})"#, + r#"describe.only("foo", function () {})"#, + r#"it.only("foo", function () {})"#, + r#"it.each("foo", () => {})"#, + r#"it.concurrent("foo", function () {})"#, + r#"test("foo", function () {})"#, + r#"test.only("foo", function () {})"#, + r#"test.concurrent("foo", function () {})"#, + r#"describe[`${"skip"}`]("foo", function () {})"#, + r#"it.todo("fill this later")"#, + "var appliedSkip = describe.skip; appliedSkip.apply(describe)", + "var calledSkip = it.skip; calledSkip.call(it)", + "({ f: function () {} }).f()", + "(a || b).f()", + "itHappensToStartWithIt()", + "testSomething()", + "xitSomethingElse()", + "xitiViewMap()", + r#" + import { pending } from "actions" + test("foo", () => { + expect(pending()).toEqual({}) + }) + "#, + " + import { test } from './test-utils'; + test('something'); + ", + ]; + + let fail_vitest = vec![ + r#"describe.skip("foo", function () {})"#, + r#"xtest("foo", function () {})"#, + r#"xit.each``("foo", function () {})"#, + r#"xtest.each``("foo", function () {})"#, + r#"xit.each([])("foo", function () {})"#, + r#"it("has title but no callback")"#, + r#"test("has title but no callback")"#, + r#"it("contains a call to pending", function () { pending() })"#, + "pending();", + r#" + import { describe } from 'vitest'; + describe.skip("foo", function () {}) + "#, + ]; + + pass.extend(pass_vitest.into_iter().map(|x| (x, None))); + fail.extend(fail_vitest.into_iter().map(|x| (x, None))); + + Tester::new(NoDisabledTests::NAME, pass, fail) + .with_jest_plugin(true) + .with_vitest_plugin(true) + .test_and_snapshot(); } diff --git a/crates/oxc_linter/src/rules/jest/prefer_to_be.rs b/crates/oxc_linter/src/rules/jest/prefer_to_be.rs index f9ef50eeebc44..814e11685a743 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_to_be.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_to_be.rs @@ -197,7 +197,7 @@ impl PreferToBe { matches!( expr, - Expression::BigintLiteral(_) + Expression::BigIntLiteral(_) | Expression::BooleanLiteral(_) | Expression::NumericLiteral(_) | Expression::NullLiteral(_) diff --git a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs index dc6192b98ef0e..17bdb3c4d53fe 100644 --- a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs +++ b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs @@ -93,7 +93,7 @@ fn get_kind_from_key(key: &PropertyKey) -> MethodKind { PropertyKey::PrivateIdentifier(_) => MethodKind::Private, PropertyKey::StringLiteral(_) => MethodKind::Normal, PropertyKey::NumericLiteral(_) - | PropertyKey::BigintLiteral(_) + | PropertyKey::BigIntLiteral(_) | PropertyKey::TemplateLiteral(_) | PropertyKey::RegExpLiteral(_) | PropertyKey::NullLiteral(_) => MethodKind::Quoted, diff --git a/crates/oxc_linter/src/rules/unicorn/no_unnecessary_await.rs b/crates/oxc_linter/src/rules/unicorn/no_unnecessary_await.rs index 1ed4cfbc98284..86cd40763622e 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_unnecessary_await.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_unnecessary_await.rs @@ -85,7 +85,7 @@ fn not_promise(expr: &Expression) -> bool { | Expression::BooleanLiteral(_) | Expression::NullLiteral(_) | Expression::NumericLiteral(_) - | Expression::BigintLiteral(_) + | Expression::BigIntLiteral(_) | Expression::RegExpLiteral(_) | Expression::StringLiteral(_) | Expression::TemplateLiteral(_) diff --git a/crates/oxc_linter/src/rules/unicorn/number_literal_case.rs b/crates/oxc_linter/src/rules/unicorn/number_literal_case.rs index a5b9eb27cba02..235fe60dddbc8 100644 --- a/crates/oxc_linter/src/rules/unicorn/number_literal_case.rs +++ b/crates/oxc_linter/src/rules/unicorn/number_literal_case.rs @@ -74,7 +74,7 @@ impl Rule for NumberLiteralCase { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { let (raw_literal, raw_span) = match node.kind() { AstKind::NumericLiteral(number) => (number.raw, number.span), - AstKind::BigintLiteral(number) => { + AstKind::BigIntLiteral(number) => { let span = number.span; (span.source_text(ctx.source_text()), span) } diff --git a/crates/oxc_linter/src/rules/unicorn/numeric_separators_style.rs b/crates/oxc_linter/src/rules/unicorn/numeric_separators_style.rs index 94209acf27598..7fd8e2191b7a4 100644 --- a/crates/oxc_linter/src/rules/unicorn/numeric_separators_style.rs +++ b/crates/oxc_linter/src/rules/unicorn/numeric_separators_style.rs @@ -101,7 +101,7 @@ impl Rule for NumericSeparatorsStyle { ); } } - AstKind::BigintLiteral(number) => { + AstKind::BigIntLiteral(number) => { let raw = number.span.source_text(ctx.source_text()); if self.only_if_contains_separator && !raw.contains('_') { diff --git a/crates/oxc_linter/src/snapshots/no_disabled_tests.snap b/crates/oxc_linter/src/snapshots/no_disabled_tests.snap index bd3e45064893b..c765a72248fc7 100644 --- a/crates/oxc_linter/src/snapshots/no_disabled_tests.snap +++ b/crates/oxc_linter/src/snapshots/no_disabled_tests.snap @@ -182,3 +182,75 @@ source: crates/oxc_linter/src/tester.rs · ───────────────── ╰──── help: "Add function argument" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Disabled test suite" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ describe.skip("foo", function () {}) + · ───────────── + ╰──── + help: "Remove the appending `.skip`" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Disabled test" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ xtest("foo", function () {}) + · ───── + ╰──── + help: "Remove x prefix" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Disabled test" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ xit.each``("foo", function () {}) + · ────────── + ╰──── + help: "Remove x prefix" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Disabled test" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ xtest.each``("foo", function () {}) + · ──────────── + ╰──── + help: "Remove x prefix" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Disabled test" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ xit.each([])("foo", function () {}) + · ──────────── + ╰──── + help: "Remove x prefix" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Test is missing function argument" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ it("has title but no callback") + · ─────────────────────────────── + ╰──── + help: "Add function argument" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Test is missing function argument" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ test("has title but no callback") + · ───────────────────────────────── + ╰──── + help: "Add function argument" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Call to pending()" + ╭─[no_disabled_tests.tsx:1:48] + 1 │ it("contains a call to pending", function () { pending() }) + · ───────── + ╰──── + help: "Remove pending() call" + + ⚠ eslint-plugin-jest(no-disabled-tests): "Call to pending()" + ╭─[no_disabled_tests.tsx:1:1] + 1 │ pending(); + · ───────── + ╰──── + help: "Remove pending() call" + + ⚠ eslint-plugin-vitest(no-disabled-tests): "Disabled test suite" + ╭─[no_disabled_tests.tsx:3:13] + 2 │ import { describe } from 'vitest'; + 3 │ describe.skip("foo", function () {}) + · ───────────── + 4 │ + ╰──── + help: "Remove the appending `.skip`" diff --git a/crates/oxc_linter/src/tester.rs b/crates/oxc_linter/src/tester.rs index d16b2bbb65be7..09742d8fb3957 100644 --- a/crates/oxc_linter/src/tester.rs +++ b/crates/oxc_linter/src/tester.rs @@ -96,6 +96,7 @@ pub struct Tester { current_working_directory: Box, import_plugin: bool, jest_plugin: bool, + vitest_plugin: bool, jsx_a11y_plugin: bool, nextjs_plugin: bool, react_perf_plugin: bool, @@ -125,6 +126,7 @@ impl Tester { jsx_a11y_plugin: false, nextjs_plugin: false, react_perf_plugin: false, + vitest_plugin: false, } } @@ -150,6 +152,11 @@ impl Tester { self } + pub fn with_vitest_plugin(mut self, yes: bool) -> Self { + self.vitest_plugin = yes; + self + } + pub fn with_jsx_a11y_plugin(mut self, yes: bool) -> Self { self.jsx_a11y_plugin = yes; self @@ -255,6 +262,7 @@ impl Tester { .with_fix(is_fix) .with_import_plugin(self.import_plugin) .with_jest_plugin(self.jest_plugin) + .with_vitest_plugin(self.vitest_plugin) .with_jsx_a11y_plugin(self.jsx_a11y_plugin) .with_nextjs_plugin(self.nextjs_plugin) .with_react_perf_plugin(self.react_perf_plugin); diff --git a/crates/oxc_linter/src/utils/jest.rs b/crates/oxc_linter/src/utils/jest.rs index b5fa3fc60c466..aebcf7cc471f8 100644 --- a/crates/oxc_linter/src/utils/jest.rs +++ b/crates/oxc_linter/src/utils/jest.rs @@ -206,7 +206,7 @@ fn collect_ids_referenced_to_import<'a>( }; let name = ctx.symbols().get_name(symbol_id); - if import_decl.source.value == "@jest/globals" { + if matches!(import_decl.source.value.as_str(), "@jest/globals" | "vitest") { let original = find_original_name(import_decl, name); let mut ret = vec![]; for reference_id in reference_ids { diff --git a/crates/oxc_linter/src/utils/mod.rs b/crates/oxc_linter/src/utils/mod.rs index faf7d84307c14..1c0410d65b084 100644 --- a/crates/oxc_linter/src/utils/mod.rs +++ b/crates/oxc_linter/src/utils/mod.rs @@ -6,6 +6,39 @@ mod react_perf; mod tree_shaking; mod unicorn; +use crate::LintContext; + pub use self::{ jest::*, jsdoc::*, nextjs::*, react::*, react_perf::*, tree_shaking::*, unicorn::*, }; + +/// Check if the Jest rule is adapted to Vitest. +/// Many Vitest rule are essentially ports of Jest plugin rules with minor modifications. +/// For these rules, we use the corresponding jest rules with some adjustments for compatibility. +pub fn is_jest_rule_adapted_to_vitest(rule_name: &str) -> bool { + matches!(rule_name, "no-disabled-tests") +} + +pub fn get_test_plugin_name(ctx: &LintContext) -> &'static str { + if is_using_vitest(ctx) { + "eslint-plugin-vitest" + } else { + "eslint-plugin-jest" + } +} + +fn is_using_vitest(ctx: &LintContext) -> bool { + // If import 'vitest' is found, we assume the user is using vitest. + if ctx + .semantic() + .module_record() + .import_entries + .iter() + .any(|entry| entry.module_request.name().as_str() == "vitest") + { + return true; + } + + // Or, find the eslint config file + ctx.rules().iter().any(|rule| rule.plugin_name == "vitest") +} diff --git a/crates/oxc_minifier/src/compressor/ast_util.rs b/crates/oxc_minifier/src/compressor/ast_util.rs index 6b63026278943..ba10b60412282 100644 --- a/crates/oxc_minifier/src/compressor/ast_util.rs +++ b/crates/oxc_minifier/src/compressor/ast_util.rs @@ -109,7 +109,7 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for Expression<'a> { Self::NumericLiteral(_) | Self::BooleanLiteral(_) | Self::StringLiteral(_) - | Self::BigintLiteral(_) + | Self::BigIntLiteral(_) | Self::NullLiteral(_) | Self::RegExpLiteral(_) | Self::MetaProperty(_) @@ -395,7 +395,7 @@ pub fn get_bigint_value(expr: &Expression) -> Option { None } } - Expression::BigintLiteral(_bigint_literal) => { + Expression::BigIntLiteral(_bigint_literal) => { // TODO: evaluate the bigint value None } @@ -473,7 +473,7 @@ pub fn get_boolean_value(expr: &Expression) -> Option { Expression::NullLiteral(_) => Some(false), Expression::BooleanLiteral(boolean_literal) => Some(boolean_literal.value), Expression::NumericLiteral(number_literal) => Some(number_literal.value != 0.0), - Expression::BigintLiteral(big_int_literal) => Some(!big_int_literal.is_zero()), + Expression::BigIntLiteral(big_int_literal) => Some(!big_int_literal.is_zero()), Expression::StringLiteral(string_literal) => Some(!string_literal.value.is_empty()), Expression::TemplateLiteral(template_literal) => { // only for `` @@ -588,7 +588,7 @@ pub fn get_string_value<'a>(expr: &'a Expression) -> Option> { Expression::NumericLiteral(number_literal) => { Some(Cow::Owned(number_literal.value.to_string())) } - Expression::BigintLiteral(big_int_literal) => { + Expression::BigIntLiteral(big_int_literal) => { Some(Cow::Owned(big_int_literal.raw.to_string())) } Expression::NullLiteral(_) => Some(Cow::Borrowed("null")), diff --git a/crates/oxc_minifier/src/compressor/fold.rs b/crates/oxc_minifier/src/compressor/fold.rs index a02537ab4f15c..4fbd47088fbf8 100644 --- a/crates/oxc_minifier/src/compressor/fold.rs +++ b/crates/oxc_minifier/src/compressor/fold.rs @@ -125,7 +125,7 @@ impl<'a> From<&Expression<'a>> for Ty { fn from(expr: &Expression<'a>) -> Self { // TODO: complete this match expr { - Expression::BigintLiteral(_) => Self::BigInt, + Expression::BigIntLiteral(_) => Self::BigInt, Expression::BooleanLiteral(_) => Self::Boolean, Expression::NullLiteral(_) => Self::Null, Expression::NumericLiteral(_) => Self::Number, @@ -616,7 +616,7 @@ impl<'a> Compressor<'a> { let bool_literal = self.ast.boolean_literal(unary_expr.span, !boolean); return Some(self.ast.literal_boolean_expression(bool_literal)); } - Expression::BigintLiteral(_) => { + Expression::BigIntLiteral(_) => { let bool_literal = self.ast.boolean_literal(unary_expr.span, !boolean); return Some(self.ast.literal_boolean_expression(bool_literal)); } @@ -676,7 +676,7 @@ impl<'a> Compressor<'a> { ); return Some(self.ast.literal_number_expression(literal)); } - Expression::BigintLiteral(_big_int_literal) => { + Expression::BigIntLiteral(_big_int_literal) => { // let value = big_int_literal.value.clone().neg(); // let literal = // self.ast.bigint_literal(unary_expr.span, value, big_int_literal.base); @@ -706,7 +706,7 @@ impl<'a> Compressor<'a> { return Some(self.ast.literal_number_expression(literal)); } } - Expression::BigintLiteral(_big_int_literal) => { + Expression::BigIntLiteral(_big_int_literal) => { // let value = big_int_literal.value.clone().not(); // let leteral = // self.ast.bigint_literal(unary_expr.span, value, big_int_literal.base); diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index bd58f0a8ad117..03a163294c190 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -19,6 +19,7 @@ pub struct ParserCheckpoint<'a> { } impl<'a> ParserImpl<'a> { + #[inline] pub(crate) fn start_span(&self) -> Span { let token = self.cur_token(); Span::new(token.start, 0) @@ -32,11 +33,13 @@ impl<'a> ParserImpl<'a> { } /// Get current token + #[inline] pub(crate) fn cur_token(&self) -> Token { self.token } /// Get current Kind + #[inline] pub(crate) fn cur_kind(&self) -> Kind { self.token.kind } @@ -63,21 +66,25 @@ impl<'a> ParserImpl<'a> { } /// Peek next token, returns EOF for final peek + #[inline] pub(crate) fn peek_token(&mut self) -> Token { self.lexer.lookahead(1) } /// Peek next kind, returns EOF for final peek + #[inline] pub(crate) fn peek_kind(&mut self) -> Kind { self.peek_token().kind } /// Peek at kind + #[inline] pub(crate) fn peek_at(&mut self, kind: Kind) -> bool { self.peek_token().kind == kind } /// Peek nth token + #[inline] pub(crate) fn nth(&mut self, n: u8) -> Token { if n == 0 { return self.cur_token(); @@ -86,16 +93,19 @@ impl<'a> ParserImpl<'a> { } /// Peek at nth kind + #[inline] pub(crate) fn nth_at(&mut self, n: u8, kind: Kind) -> bool { self.nth(n).kind == kind } /// Peek nth kind + #[inline] pub(crate) fn nth_kind(&mut self, n: u8) -> Kind { self.nth(n).kind } /// Checks if the current index has token `Kind` + #[inline] pub(crate) fn at(&self, kind: Kind) -> bool { self.cur_kind() == kind } @@ -128,6 +138,7 @@ impl<'a> ParserImpl<'a> { } /// Advance and return true if we are at `Kind`, return false otherwise + #[inline] pub(crate) fn eat(&mut self, kind: Kind) -> bool { if self.at(kind) { self.advance(kind); @@ -137,6 +148,7 @@ impl<'a> ParserImpl<'a> { } /// Advance and return true if we are at `Kind` + #[inline] pub(crate) fn bump(&mut self, kind: Kind) { if self.at(kind) { self.advance(kind); @@ -144,11 +156,13 @@ impl<'a> ParserImpl<'a> { } /// Advance any token + #[inline] pub(crate) fn bump_any(&mut self) { self.advance(self.cur_kind()); } /// Advance and change token type, useful for changing keyword to ident + #[inline] pub(crate) fn bump_remap(&mut self, kind: Kind) { self.advance(kind); } @@ -185,6 +199,7 @@ impl<'a> ParserImpl<'a> { /// Expect a `Kind` or return error /// # Errors + #[inline] pub(crate) fn expect(&mut self, kind: Kind) -> Result<()> { self.expect_without_advance(kind)?; self.advance(kind); diff --git a/crates/oxc_parser/src/js/arrow.rs b/crates/oxc_parser/src/js/arrow.rs index cb8521e4d344d..2998766146452 100644 --- a/crates/oxc_parser/src/js/arrow.rs +++ b/crates/oxc_parser/src/js/arrow.rs @@ -216,10 +216,9 @@ impl<'a> ParserImpl<'a> { } _ => unreachable!(), }; - let span = ident.span; - let params_span = self.end_span(span); + let params_span = self.end_span(ident.span); let ident = self.ast.binding_pattern_identifier(ident); - let pattern = self.ast.binding_pattern(span, ident, None, false); + let pattern = self.ast.binding_pattern(ident, None, false); let formal_parameter = self.ast.plain_formal_parameter(params_span, pattern); self.ast.formal_parameters( params_span, diff --git a/crates/oxc_parser/src/js/binding.rs b/crates/oxc_parser/src/js/binding.rs index 1008b5a6b59e4..6e6ccd9f1a4cd 100644 --- a/crates/oxc_parser/src/js/binding.rs +++ b/crates/oxc_parser/src/js/binding.rs @@ -20,7 +20,6 @@ impl<'a> ParserImpl<'a> { &mut self, allow_question: bool, ) -> Result> { - let span = self.start_span(); let mut kind = self.parse_binding_pattern_kind()?; let optional = if allow_question && self.ts_enabled() { self.eat(Kind::Question) } else { false }; @@ -28,10 +27,10 @@ impl<'a> ParserImpl<'a> { if let Some(type_annotation) = &type_annotation { Self::extend_binding_pattern_span_end(type_annotation.span, &mut kind); } - Ok(self.ast.binding_pattern(self.end_span(span), kind, type_annotation, optional)) + Ok(self.ast.binding_pattern(kind, type_annotation, optional)) } - pub(super) fn parse_binding_pattern_kind(&mut self) -> Result> { + pub(crate) fn parse_binding_pattern_kind(&mut self) -> Result> { match self.cur_kind() { Kind::LCurly => self.parse_object_binding_pattern(), Kind::LBrack => self.parse_array_binding_pattern(), @@ -73,7 +72,7 @@ impl<'a> ParserImpl<'a> { } // The span is not extended to its type_annotation let type_annotation = self.parse_ts_type_annotation()?; - let pattern = self.ast.binding_pattern(self.end_span(span), kind, type_annotation, false); + let pattern = self.ast.binding_pattern(kind, type_annotation, false); // Rest element does not allow `= initializer`, . let argument = self .context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?; @@ -110,7 +109,7 @@ impl<'a> ParserImpl<'a> { shorthand = true; let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone()); let identifier = self.ast.binding_pattern_identifier(binding_identifier); - let left = self.ast.binding_pattern(ident.span, identifier, None, false); + let left = self.ast.binding_pattern(identifier, None, false); self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left))? } else { return Err(self.unexpected()); diff --git a/crates/oxc_parser/src/js/declaration.rs b/crates/oxc_parser/src/js/declaration.rs index 81ab133b5c0a2..88f774d50a5f7 100644 --- a/crates/oxc_parser/src/js/declaration.rs +++ b/crates/oxc_parser/src/js/declaration.rs @@ -114,17 +114,9 @@ impl<'a> ParserImpl<'a> { if let Some(type_annotation) = &type_annotation { Self::extend_binding_pattern_span_end(type_annotation.span, &mut binding_kind); } - ( - self.ast.binding_pattern( - self.end_span(span), - binding_kind, - type_annotation, - optional, - ), - definite, - ) + (self.ast.binding_pattern(binding_kind, type_annotation, optional), definite) } else { - (self.ast.binding_pattern(self.end_span(span), binding_kind, None, false), false) + (self.ast.binding_pattern(binding_kind, None, false), false) }; let init = diff --git a/crates/oxc_parser/src/js/list.rs b/crates/oxc_parser/src/js/list.rs index c2c1f10620e91..7ac7cb5b918d2 100644 --- a/crates/oxc_parser/src/js/list.rs +++ b/crates/oxc_parser/src/js/list.rs @@ -215,8 +215,27 @@ impl<'a> SeparatedList<'a> for SequenceExpressionList<'a> { // read everything as expression and map to it to either // ParenthesizedExpression or ArrowFormalParameters later fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()> { - let element = p.parse_assignment_expression_or_higher()?; - self.elements.push(element); + let element = p.parse_assignment_expression_or_higher(); + self.elements.push(element?); + Ok(()) + } + + fn parse_list(&mut self, p: &mut ParserImpl<'a>) -> Result<()> { + p.expect(self.open())?; + + let mut first = true; + + while !p.at(self.close()) && !p.at(Kind::Eof) { + if first { + first = false; + } else { + p.expect(self.separator())?; + } + + self.parse_element(p)?; + } + + p.expect(self.close())?; Ok(()) } } diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 70222d21f558e..3ead79bc10ed5 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -396,7 +396,6 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_ts_type_assertion(&mut self) -> Result> { let span = self.start_span(); - self.re_lex_ts_l_angle(); self.expect(Kind::LAngle)?; let type_annotation = self.parse_ts_type()?; self.expect(Kind::RAngle)?; diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index 80ad90879526f..dc2a39ee210cb 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -9,7 +9,6 @@ use super::list::{ }; use crate::{ diagnostics, - js::list::{ArrayPatternList, ObjectPatternProperties}, lexer::Kind, list::{NormalList, SeparatedList}, modifiers::ModifierFlags, @@ -19,18 +18,91 @@ use crate::{ impl<'a> ParserImpl<'a> { pub(crate) fn parse_ts_type(&mut self) -> Result> { - if self.is_at_constructor_type() { - return self.parse_ts_constructor_type(); + if self.is_start_of_function_type_or_constructor_type() { + return self.parse_function_or_constructor_type(); } + let left_span = self.start_span(); + let left = self.parse_ts_union_type()?; + self.parse_ts_conditional_type(left_span, left) + } + + fn parse_function_or_constructor_type(&mut self) -> Result> { + let span = self.start_span(); + let r#abstract = self.eat(Kind::Abstract); + let is_constructor_type = self.eat(Kind::New); + let type_parameters = self.parse_ts_type_parameters()?; + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; + self.expect(Kind::Arrow)?; + let return_type = { + let return_type_span = self.start_span(); + let return_type = self.parse_ts_return_type()?; + self.ast.ts_type_annotation(self.end_span(return_type_span), return_type) + }; - if self.is_at_function_type() { - return self.parse_ts_function_type(); + let span = self.end_span(span); + Ok(if is_constructor_type { + if let Some(this_param) = &this_param { + // type Foo = new (this: number) => any; + self.error(diagnostics::ts_constructor_this_parameter(this_param.span)); + } + self.ast.ts_constructor_type(span, r#abstract, params, return_type, type_parameters) + } else { + self.ast.ts_function_type(span, this_param, params, return_type, type_parameters) + }) + } + + fn is_start_of_function_type_or_constructor_type(&mut self) -> bool { + if self.at(Kind::LAngle) { + return true; + } + if self.at(Kind::LParen) && self.lookahead(Self::is_unambiguously_start_of_function_type) { + return true; } + self.at(Kind::New) || (self.at(Kind::Abstract) && self.peek_at(Kind::New)) + } - let left_span = self.start_span(); - let left = self.parse_ts_union_type()?; + fn is_unambiguously_start_of_function_type(&mut self) -> bool { + self.bump_any(); + // ( ) + // ( ... + if matches!(self.cur_kind(), Kind::RParen | Kind::Dot3) { + return true; + } + if self.skip_parameter_start() { + // ( xxx : + // ( xxx , + // ( xxx ? + // ( xxx = + if matches!(self.cur_kind(), Kind::Colon | Kind::Comma | Kind::Question | Kind::Eq) { + return true; + } + // ( xxx ) => + if self.eat(Kind::RParen) && self.at(Kind::Arrow) { + return true; + } + } + false + } - self.parse_ts_conditional_type(left_span, left) + fn skip_parameter_start(&mut self) -> bool { + // Skip modifiers + loop { + if self.cur_kind().is_modifier_kind() && !self.peek_at(Kind::Comma) { + self.bump_any(); + } else { + break; + } + } + if self.cur_kind().is_identifier() || self.at(Kind::This) { + self.bump_any(); + return true; + } + if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) + && self.parse_binding_pattern_kind().is_ok() + { + return true; + } + false } pub(crate) fn parse_ts_type_parameters( @@ -162,10 +234,6 @@ impl<'a> ParserImpl<'a> { Ok(left) } - fn is_at_constructor_type(&mut self) -> bool { - self.at(Kind::New) || (self.at(Kind::Abstract) && self.peek_at(Kind::New)) - } - // test ts ts_union_type // type A = string | number; // type B = | A | void | null; @@ -474,51 +542,6 @@ impl<'a> ParserImpl<'a> { Ok(self.ast.ts_tuple_type(self.end_span(span), elements)) } - fn is_at_function_type(&mut self) -> bool { - if self.at(Kind::LAngle) { - return true; - } - - if !self.at(Kind::LParen) { - return false; - } - - let checkpoint = self.checkpoint(); - - self.bump_any(); // bump ( - - if self.at(Kind::RParen) || self.at(Kind::Dot3) { - self.rewind(checkpoint); - return true; - } - - let mut is_function_parameter_start = - self.at(Kind::This) || self.cur_kind().is_binding_identifier(); - - if is_function_parameter_start { - self.bump_any(); - } - - if match self.cur_kind() { - Kind::LBrack => ArrayPatternList::parse(self).is_ok(), - Kind::LCurly => ObjectPatternProperties::parse(self).is_ok(), - _ => false, - } { - is_function_parameter_start = true; - } - - let result = if is_function_parameter_start { - matches!(self.cur_kind(), Kind::Colon | Kind::Eq | Kind::Comma | Kind::Question) - || (self.at(Kind::RParen) && self.peek_at(Kind::Arrow)) - } else { - false - }; - - self.rewind(checkpoint); - - result - } - fn is_at_mapped_type(&mut self) -> bool { if !self.at(Kind::LCurly) { return false; @@ -638,7 +661,7 @@ impl<'a> ParserImpl<'a> { Expression::BooleanLiteral(literal) => TSLiteral::BooleanLiteral(literal), Expression::NullLiteral(literal) => TSLiteral::NullLiteral(literal), Expression::NumericLiteral(literal) => TSLiteral::NumericLiteral(literal), - Expression::BigintLiteral(literal) => TSLiteral::BigintLiteral(literal), + Expression::BigIntLiteral(literal) => TSLiteral::BigIntLiteral(literal), Expression::RegExpLiteral(literal) => TSLiteral::RegExpLiteral(literal), Expression::StringLiteral(literal) => TSLiteral::StringLiteral(literal), Expression::TemplateLiteral(literal) => TSLiteral::TemplateLiteral(literal), @@ -731,49 +754,6 @@ impl<'a> ParserImpl<'a> { Ok(TSImportAttributes { span, elements }) } - fn parse_ts_constructor_type(&mut self) -> Result> { - let span = self.start_span(); - let r#abstract = self.eat(Kind::Abstract); - self.expect(Kind::New)?; - let type_parameters = self.parse_ts_type_parameters()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; - - if let Some(this_param) = this_param { - // type Foo = new (this: number) => any; - self.error(diagnostics::ts_constructor_this_parameter(this_param.span)); - } - - self.expect(Kind::Arrow)?; - let return_type_span = self.start_span(); - let return_type = self.parse_ts_return_type()?; - let return_type = self.ast.ts_type_annotation(self.end_span(return_type_span), return_type); - - Ok(self.ast.ts_constructor_type( - self.end_span(span), - r#abstract, - params, - return_type, - type_parameters, - )) - } - - fn parse_ts_function_type(&mut self) -> Result> { - let span = self.start_span(); - let type_parameters = self.parse_ts_type_parameters()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; - let return_type_span = self.start_span(); - self.expect(Kind::Arrow)?; - let return_type = self.parse_ts_return_type()?; - let return_type = self.ast.ts_type_annotation(self.end_span(return_type_span), return_type); - Ok(self.ast.ts_function_type( - self.end_span(span), - this_param, - params, - return_type, - type_parameters, - )) - } - fn parse_ts_infer_type(&mut self) -> Result> { let span = self.start_span(); self.expect(Kind::Infer)?; diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index 164e70a8e812e..b83cb679184db 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -842,7 +842,7 @@ impl<'a> Format<'a> for TSLiteralType<'a> { TSLiteral::BooleanLiteral(v) => v.format(p), TSLiteral::NullLiteral(v) => v.format(p), TSLiteral::NumericLiteral(v) => v.format(p), - TSLiteral::BigintLiteral(v) => v.format(p), + TSLiteral::BigIntLiteral(v) => v.format(p), TSLiteral::RegExpLiteral(v) => v.format(p), TSLiteral::StringLiteral(v) => v.format(p), TSLiteral::TemplateLiteral(v) => v.format(p), @@ -1250,7 +1250,7 @@ impl<'a> Format<'a> for Expression<'a> { Self::BooleanLiteral(lit) => lit.format(p), Self::NullLiteral(lit) => lit.format(p), Self::NumericLiteral(lit) => lit.format(p), - Self::BigintLiteral(lit) => lit.format(p), + Self::BigIntLiteral(lit) => lit.format(p), Self::RegExpLiteral(lit) => lit.format(p), Self::StringLiteral(lit) => lit.format(p), Self::Identifier(ident) => ident.format(p), diff --git a/crates/oxc_semantic/src/checker/typescript.rs b/crates/oxc_semantic/src/checker/typescript.rs index d637cd5306bbc..263b043aa6864 100644 --- a/crates/oxc_semantic/src/checker/typescript.rs +++ b/crates/oxc_semantic/src/checker/typescript.rs @@ -48,7 +48,8 @@ pub fn check_formal_parameters(params: &FormalParameters, ctx: &SemanticBuilder< check_duplicate_bound_names(params, ctx); } - let is_inside_constructor = ctx.current_scope_flags().is_constructor(); + let is_inside_constructor = + !params.kind.is_signature() && ctx.current_scope_flags().is_constructor(); let mut has_optional = false; for item in ¶ms.items { diff --git a/crates/oxc_semantic/src/dot.rs b/crates/oxc_semantic/src/dot.rs index d939943b25791..df3354ef781fb 100644 --- a/crates/oxc_semantic/src/dot.rs +++ b/crates/oxc_semantic/src/dot.rs @@ -35,7 +35,7 @@ impl<'a, 'b> DebugDotContext<'a, 'b> { AstKind::NumericLiteral(lit) => Some(lit.value.to_string()), AstKind::BooleanLiteral(lit) => Some(lit.value.to_string()), AstKind::StringLiteral(lit) => Some(lit.value.to_string()), - AstKind::BigintLiteral(lit) => Some(lit.raw.to_string()), + AstKind::BigIntLiteral(lit) => Some(lit.raw.to_string()), AstKind::NullLiteral(_) => Some("null".to_string()), _ => None, } diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index 580bf369492ce..ee5abaf2e0b9c 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -114,7 +114,6 @@ impl<'a> ArrowFunctions<'a> { if let Some(id) = &self.this_var { let binding_pattern = self.ctx.ast.binding_pattern( - SPAN, self.ctx.ast.binding_pattern_identifier(id.create_binding_identifier()), None, false, diff --git a/crates/oxc_transformer/src/helpers/module_imports.rs b/crates/oxc_transformer/src/helpers/module_imports.rs index dd045bb5328c5..dad026b8e529e 100644 --- a/crates/oxc_transformer/src/helpers/module_imports.rs +++ b/crates/oxc_transformer/src/helpers/module_imports.rs @@ -134,7 +134,7 @@ impl<'a> ModuleImports<'a> { name: name.imported, symbol_id: Cell::new(Some(name.symbol_id)), }; - self.ast.binding_pattern(SPAN, self.ast.binding_pattern_identifier(ident), None, false) + self.ast.binding_pattern(self.ast.binding_pattern_identifier(ident), None, false) }; let decl = { let init = self.ast.call_expression(SPAN, callee, args, false, None); diff --git a/crates/oxc_transformer/src/react/jsx_source.rs b/crates/oxc_transformer/src/react/jsx_source.rs index aa865ab51c712..185bf81d7a9b6 100644 --- a/crates/oxc_transformer/src/react/jsx_source.rs +++ b/crates/oxc_transformer/src/react/jsx_source.rs @@ -152,7 +152,7 @@ impl<'a> ReactJsxSource<'a> { let id = { let ident = filename_var.create_binding_identifier(); let ident = self.ctx.ast.binding_pattern_identifier(ident); - self.ctx.ast.binding_pattern(SPAN, ident, None, false) + self.ctx.ast.binding_pattern(ident, None, false) }; let decl = { let string = self.ctx.ast.string_literal(SPAN, &self.ctx.source_path.to_string_lossy()); diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index 83307813394e6..7d053a0a43e71 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -67,7 +67,7 @@ impl<'a> TypeScriptEnum<'a> { let span = decl.span; let ident = decl.id.clone(); let kind = self.ctx.ast.binding_pattern_identifier(ident); - let id = self.ctx.ast.binding_pattern(SPAN, kind, None, false); + let id = self.ctx.ast.binding_pattern(kind, None, false); // ((Foo) => { let params = @@ -127,7 +127,7 @@ impl<'a> TypeScriptEnum<'a> { let binding_identifier = BindingIdentifier::new(SPAN, enum_name.clone()); let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier); - let binding = self.ctx.ast.binding_pattern(SPAN, binding_pattern_kind, None, false); + let binding = self.ctx.ast.binding_pattern(binding_pattern_kind, None, false); let decl = self.ctx.ast.variable_declarator(SPAN, kind, binding, Some(call_expression), false); diff --git a/crates/oxc_transformer/src/typescript/module.rs b/crates/oxc_transformer/src/typescript/module.rs index 6ee8d2b7fde07..ce55b4b9f991c 100644 --- a/crates/oxc_transformer/src/typescript/module.rs +++ b/crates/oxc_transformer/src/typescript/module.rs @@ -35,7 +35,7 @@ impl<'a> TypeScript<'a> { let decls = { let binding_identifier = BindingIdentifier::new(SPAN, decl.id.name.clone()); let binding_pattern_kind = self.ctx.ast.binding_pattern_identifier(binding_identifier); - let binding = self.ctx.ast.binding_pattern(SPAN, binding_pattern_kind, None, false); + let binding = self.ctx.ast.binding_pattern(binding_pattern_kind, None, false); let decl_span = decl.span; let init = match &mut decl.module_reference { diff --git a/crates/oxc_transformer/src/typescript/namespace.rs b/crates/oxc_transformer/src/typescript/namespace.rs index 5937d9dd28c3c..592408299db88 100644 --- a/crates/oxc_transformer/src/typescript/namespace.rs +++ b/crates/oxc_transformer/src/typescript/namespace.rs @@ -282,7 +282,7 @@ impl<'a> TypeScript<'a> { let declarations = { let ident = BindingIdentifier::new(SPAN, name); let pattern_kind = self.ctx.ast.binding_pattern_identifier(ident); - let binding = self.ctx.ast.binding_pattern(SPAN, pattern_kind, None, false); + let binding = self.ctx.ast.binding_pattern(pattern_kind, None, false); let decl = self.ctx.ast.variable_declarator(SPAN, kind, binding, None, false); self.ctx.ast.new_vec_single(decl) }; @@ -314,7 +314,7 @@ impl<'a> TypeScript<'a> { let params = { let ident = self.ctx.ast.binding_pattern_identifier(BindingIdentifier::new(SPAN, arg_name)); - let pattern = self.ctx.ast.binding_pattern(SPAN, ident, None, false); + let pattern = self.ctx.ast.binding_pattern(ident, None, false); let items = self.ctx.ast.new_vec_single(self.ctx.ast.plain_formal_parameter(SPAN, pattern)); self.ctx.ast.formal_parameters( diff --git a/crates/oxc_traverse/scripts/lib/parse.mjs b/crates/oxc_traverse/scripts/lib/parse.mjs index afac39d607fc8..e7b661e04bd0f 100644 --- a/crates/oxc_traverse/scripts/lib/parse.mjs +++ b/crates/oxc_traverse/scripts/lib/parse.mjs @@ -2,7 +2,7 @@ import {readFile} from 'fs/promises'; import {join as pathJoin} from 'path'; import {fileURLToPath} from 'url'; import assert from 'assert'; -import {typeAndWrappers} from './utils.mjs'; +import {typeAndWrappers, snakeToCamel} from './utils.mjs'; const FILENAMES = ['js.rs', 'jsx.rs', 'literal.rs', 'ts.rs']; @@ -37,7 +37,7 @@ function parseFile(code, filename, types) { line = lines[++lineIndex]; } scopeArgsStr += ` ${line.slice(0, -2)}`; - scopeArgsStr = scopeArgsStr.trim().replace(/ +/g, ' '); + scopeArgsStr = scopeArgsStr.trim().replace(/ +/g, ' ').replace(/,$/, ''); scopeArgs = parseScopeArgs(scopeArgsStr, filename, lineIndex); } @@ -68,8 +68,11 @@ function parseFile(code, filename, types) { function parseStruct(name, rawName, lines, scopeArgs, filename, startLineIndex) { const fields = []; for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - if (line.startsWith('#[')) { + let line = lines[i]; + const isScopeEntry = line === '#[scope(enter_before)]'; + if (isScopeEntry) { + line = lines[++i]; + } else if (line.startsWith('#[')) { while (!lines[i].endsWith(']')) { i++; } @@ -86,6 +89,8 @@ function parseStruct(name, rawName, lines, scopeArgs, filename, startLineIndex) {name: innerTypeName, wrappers} = typeAndWrappers(typeName); fields.push({name, typeName, rawName, rawTypeName, innerTypeName, wrappers}); + + if (isScopeEntry) scopeArgs.enterScopeBefore = name; } return {kind: 'struct', name, rawName, fields, scopeArgs}; } @@ -128,7 +133,7 @@ function parseScopeArgs(argsStr, filename, lineIndex) { while (true) { const [key] = matchAndConsume(/^([a-z_]+)\(/); assert( - ['scope', 'scope_if', 'strict_if', 'enter_scope_before'].includes(key), + ['scope', 'scope_if', 'strict_if'].includes(key), `Unexpected visited_node macro arg: ${key}` ); @@ -145,7 +150,8 @@ function parseScopeArgs(argsStr, filename, lineIndex) { } assert(bracketCount === 0); - args[key] = argsStr.slice(0, index).trim(); + const camelKey = key.replace(/_([a-z])/g, (_, c) => c.toUpperCase()); + args[camelKey] = argsStr.slice(0, index).trim(); argsStr = argsStr.slice(index + 1); if (argsStr === '') break; diff --git a/crates/oxc_traverse/scripts/lib/walk.mjs b/crates/oxc_traverse/scripts/lib/walk.mjs index 047b5acbddbc8..8ceb6eff2e26b 100644 --- a/crates/oxc_traverse/scripts/lib/walk.mjs +++ b/crates/oxc_traverse/scripts/lib/walk.mjs @@ -61,7 +61,7 @@ function generateWalkForStruct(type, types) { let scopeEnterField, enterScopeCode = '', exitScopeCode = ''; if (scopeArgs && scopeIdField) { // Get field to enter scope before - const enterFieldName = scopeArgs.enter_scope_before; + const enterFieldName = scopeArgs.enterScopeBefore; if (enterFieldName) { scopeEnterField = visitedFields.find(field => field.name === enterFieldName); assert( diff --git a/crates/oxc_traverse/src/ancestor.rs b/crates/oxc_traverse/src/ancestor.rs index cfefec7ec9b8f..7eebf90dabb60 100644 --- a/crates/oxc_traverse/src/ancestor.rs +++ b/crates/oxc_traverse/src/ancestor.rs @@ -4922,7 +4922,6 @@ impl<'a> CatchParameterWithoutPattern<'a> { } } -pub(crate) const OFFSET_BINDING_PATTERN_SPAN: usize = offset_of!(BindingPattern, span); pub(crate) const OFFSET_BINDING_PATTERN_KIND: usize = offset_of!(BindingPattern, kind); pub(crate) const OFFSET_BINDING_PATTERN_TYPE_ANNOTATION: usize = offset_of!(BindingPattern, type_annotation); @@ -4933,11 +4932,6 @@ pub(crate) const OFFSET_BINDING_PATTERN_OPTIONAL: usize = offset_of!(BindingPatt pub struct BindingPatternWithoutKind<'a>(pub(crate) *const BindingPattern<'a>); impl<'a> BindingPatternWithoutKind<'a> { - #[inline] - pub fn span(&self) -> &Span { - unsafe { &*((self.0 as *const u8).add(OFFSET_BINDING_PATTERN_SPAN) as *const Span) } - } - #[inline] pub fn type_annotation(&self) -> &Option>> { unsafe { @@ -4957,11 +4951,6 @@ impl<'a> BindingPatternWithoutKind<'a> { pub struct BindingPatternWithoutTypeAnnotation<'a>(pub(crate) *const BindingPattern<'a>); impl<'a> BindingPatternWithoutTypeAnnotation<'a> { - #[inline] - pub fn span(&self) -> &Span { - unsafe { &*((self.0 as *const u8).add(OFFSET_BINDING_PATTERN_SPAN) as *const Span) } - } - #[inline] pub fn kind(&self) -> &BindingPatternKind<'a> { unsafe { diff --git a/crates/oxc_traverse/src/walk.rs b/crates/oxc_traverse/src/walk.rs index c53a9771c1673..c77ca99a7ed47 100644 --- a/crates/oxc_traverse/src/walk.rs +++ b/crates/oxc_traverse/src/walk.rs @@ -77,7 +77,7 @@ pub(crate) unsafe fn walk_expression<'a, Tr: Traverse<'a>>( Expression::NumericLiteral(node) => { walk_numeric_literal(traverser, (&mut **node) as *mut _, ctx) } - Expression::BigintLiteral(node) => { + Expression::BigIntLiteral(node) => { walk_big_int_literal(traverser, (&mut **node) as *mut _, ctx) } Expression::RegExpLiteral(node) => { @@ -264,7 +264,7 @@ pub(crate) unsafe fn walk_array_expression_element<'a, Tr: Traverse<'a>>( ArrayExpressionElement::BooleanLiteral(_) | ArrayExpressionElement::NullLiteral(_) | ArrayExpressionElement::NumericLiteral(_) - | ArrayExpressionElement::BigintLiteral(_) + | ArrayExpressionElement::BigIntLiteral(_) | ArrayExpressionElement::RegExpLiteral(_) | ArrayExpressionElement::StringLiteral(_) | ArrayExpressionElement::TemplateLiteral(_) @@ -398,7 +398,7 @@ pub(crate) unsafe fn walk_property_key<'a, Tr: Traverse<'a>>( PropertyKey::BooleanLiteral(_) | PropertyKey::NullLiteral(_) | PropertyKey::NumericLiteral(_) - | PropertyKey::BigintLiteral(_) + | PropertyKey::BigIntLiteral(_) | PropertyKey::RegExpLiteral(_) | PropertyKey::StringLiteral(_) | PropertyKey::TemplateLiteral(_) @@ -713,7 +713,7 @@ pub(crate) unsafe fn walk_argument<'a, Tr: Traverse<'a>>( Argument::BooleanLiteral(_) | Argument::NullLiteral(_) | Argument::NumericLiteral(_) - | Argument::BigintLiteral(_) + | Argument::BigIntLiteral(_) | Argument::RegExpLiteral(_) | Argument::StringLiteral(_) | Argument::TemplateLiteral(_) @@ -1679,7 +1679,7 @@ pub(crate) unsafe fn walk_for_statement_init<'a, Tr: Traverse<'a>>( ForStatementInit::BooleanLiteral(_) | ForStatementInit::NullLiteral(_) | ForStatementInit::NumericLiteral(_) - | ForStatementInit::BigintLiteral(_) + | ForStatementInit::BigIntLiteral(_) | ForStatementInit::RegExpLiteral(_) | ForStatementInit::StringLiteral(_) | ForStatementInit::TemplateLiteral(_) @@ -3057,7 +3057,7 @@ pub(crate) unsafe fn walk_export_default_declaration_kind<'a, Tr: Traverse<'a>>( ExportDefaultDeclarationKind::BooleanLiteral(_) | ExportDefaultDeclarationKind::NullLiteral(_) | ExportDefaultDeclarationKind::NumericLiteral(_) - | ExportDefaultDeclarationKind::BigintLiteral(_) + | ExportDefaultDeclarationKind::BigIntLiteral(_) | ExportDefaultDeclarationKind::RegExpLiteral(_) | ExportDefaultDeclarationKind::StringLiteral(_) | ExportDefaultDeclarationKind::TemplateLiteral(_) @@ -3336,7 +3336,7 @@ pub(crate) unsafe fn walk_jsx_expression<'a, Tr: Traverse<'a>>( JSXExpression::BooleanLiteral(_) | JSXExpression::NullLiteral(_) | JSXExpression::NumericLiteral(_) - | JSXExpression::BigintLiteral(_) + | JSXExpression::BigIntLiteral(_) | JSXExpression::RegExpLiteral(_) | JSXExpression::StringLiteral(_) | JSXExpression::TemplateLiteral(_) @@ -3693,7 +3693,7 @@ pub(crate) unsafe fn walk_ts_enum_member_name<'a, Tr: Traverse<'a>>( TSEnumMemberName::BooleanLiteral(_) | TSEnumMemberName::NullLiteral(_) | TSEnumMemberName::NumericLiteral(_) - | TSEnumMemberName::BigintLiteral(_) + | TSEnumMemberName::BigIntLiteral(_) | TSEnumMemberName::RegExpLiteral(_) | TSEnumMemberName::StringLiteral(_) | TSEnumMemberName::TemplateLiteral(_) @@ -3786,7 +3786,7 @@ pub(crate) unsafe fn walk_ts_literal<'a, Tr: Traverse<'a>>( TSLiteral::NumericLiteral(node) => { walk_numeric_literal(traverser, (&mut **node) as *mut _, ctx) } - TSLiteral::BigintLiteral(node) => { + TSLiteral::BigIntLiteral(node) => { walk_big_int_literal(traverser, (&mut **node) as *mut _, ctx) } TSLiteral::RegExpLiteral(node) => { diff --git a/tasks/ast_codegen/Cargo.toml b/tasks/ast_codegen/Cargo.toml new file mode 100644 index 0000000000000..87c5c18cc94a0 --- /dev/null +++ b/tasks/ast_codegen/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "oxc_ast_codegen" +version = "0.0.0" +publish = false +edition.workspace = true +license.workspace = true + +[lints] +workspace = true + + +[[bin]] +name = "oxc_ast_codegen" +test = false + +[dependencies] +syn = { workspace = true, features = ["full", "extra-traits", "clone-impls", "derive", "parsing", "printing", "proc-macro"] } +quote = { workspace = true } +proc-macro2 = { workspace = true } +itertools = { workspace = true } +serde = { workspace = true, features = ["derive"] } +regex = { workspace = true } +prettyplease = { workspace = true } +lazy_static = { workspace = true } + +[package.metadata.cargo-shear] +ignored = ["prettyplease"] diff --git a/tasks/ast_codegen/src/defs.rs b/tasks/ast_codegen/src/defs.rs new file mode 100644 index 0000000000000..1733d8e7503d5 --- /dev/null +++ b/tasks/ast_codegen/src/defs.rs @@ -0,0 +1,115 @@ +use super::{REnum, RStruct, RType}; +use crate::{schema::Inherit, TypeName}; +use quote::ToTokens; +use serde::Serialize; + +#[derive(Debug, Serialize)] +pub enum TypeDef { + Struct(StructDef), + Enum(EnumDef), +} + +#[derive(Debug, Serialize)] +pub struct StructDef { + name: TypeName, + fields: Vec, + has_lifetime: bool, +} + +#[derive(Debug, Serialize)] +pub struct EnumDef { + name: TypeName, + variants: Vec, + /// For `@inherits` inherited enum variants + inherits: Vec, + has_lifetime: bool, +} + +#[derive(Debug, Serialize)] +pub struct EnumVariantDef { + name: TypeName, + fields: Vec, + discriminant: Option, +} + +#[derive(Debug, Serialize)] +pub struct EnumInheritDef { + super_name: String, + variants: Vec, +} + +#[derive(Debug, Serialize)] +pub struct FieldDef { + /// `None` if unnamed + name: Option, + r#type: TypeName, +} + +impl From<&RType> for Option { + fn from(rtype: &RType) -> Self { + match rtype { + RType::Enum(it) => Some(TypeDef::Enum(it.into())), + RType::Struct(it) => Some(TypeDef::Struct(it.into())), + _ => None, + } + } +} + +impl From<&REnum> for EnumDef { + fn from(it @ REnum { item, meta }: &REnum) -> Self { + Self { + name: it.ident().to_string(), + variants: item.variants.iter().map(Into::into).collect(), + has_lifetime: item.generics.lifetimes().count() > 0, + inherits: meta.inherits.iter().map(Into::into).collect(), + } + } +} + +impl From<&RStruct> for StructDef { + fn from(it @ RStruct { item, .. }: &RStruct) -> Self { + Self { + name: it.ident().to_string(), + fields: item.fields.iter().map(Into::into).collect(), + has_lifetime: item.generics.lifetimes().count() > 0, + } + } +} + +impl From<&syn::Variant> for EnumVariantDef { + fn from(variant: &syn::Variant) -> Self { + Self { + name: variant.ident.to_string(), + discriminant: variant.discriminant.as_ref().map(|(_, disc)| match disc { + syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }) => { + lit.base10_parse().expect("invalid base10 enum discriminant") + } + _ => panic!("invalid enum discriminant"), + }), + fields: variant.fields.iter().map(Into::into).collect(), + } + } +} + +impl From<&Inherit> for EnumInheritDef { + fn from(inherit: &Inherit) -> Self { + match inherit { + Inherit::Linked { super_, variants } => Self { + super_name: super_.into(), + variants: variants.iter().map(Into::into).collect(), + }, + Inherit::Unlinked(_) => { + panic!("`Unlinked` inherits can't be converted to a valid `EnumInheritDef`!") + } + } + } +} + +impl From<&syn::Field> for FieldDef { + fn from(field: &syn::Field) -> Self { + Self { + name: field.ident.as_ref().map(ToString::to_string), + r#type: field.ty.to_token_stream().to_string().replace(' ', ""), + } + } +} diff --git a/tasks/ast_codegen/src/generators/ast.rs b/tasks/ast_codegen/src/generators/ast.rs new file mode 100644 index 0000000000000..0bac1e0db3e27 --- /dev/null +++ b/tasks/ast_codegen/src/generators/ast.rs @@ -0,0 +1,17 @@ +use quote::ToTokens; + +use crate::{CodegenCtx, Generator, GeneratorOutput}; + +pub struct AstGenerator; + +impl Generator for AstGenerator { + fn name(&self) -> &'static str { + "AstGenerator" + } + + fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput { + let output = + ctx.modules.iter().map(|it| (it.module.clone(), it.to_token_stream())).collect(); + GeneratorOutput::Many(output) + } +} diff --git a/tasks/ast_codegen/src/generators/ast_kind.rs b/tasks/ast_codegen/src/generators/ast_kind.rs new file mode 100644 index 0000000000000..c1e05afbe4679 --- /dev/null +++ b/tasks/ast_codegen/src/generators/ast_kind.rs @@ -0,0 +1,162 @@ +use itertools::Itertools; +use quote::quote; +use syn::{parse_quote, Arm, Ident, Type, Variant}; + +use crate::{schema::RType, CodegenCtx, Generator, GeneratorOutput}; + +use super::generated_header; + +pub struct AstKindGenerator; + +const BLACK_LIST: [&str; 68] = [ + "Expression", + "ObjectPropertyKind", + "TemplateElement", + "ComputedMemberExpression", + "StaticMemberExpression", + "PrivateFieldExpression", + "AssignmentTargetPattern", + "ArrayAssignmentTarget", + "ObjectAssignmentTarget", + "AssignmentTargetRest", + "AssignmentTargetMaybeDefault", + "AssignmentTargetProperty", + "AssignmentTargetPropertyIdentifier", + "AssignmentTargetPropertyProperty", + "ChainElement", + "Statement", + "Declaration", + "ForStatementLeft", + "BindingPattern", + "BindingPatternKind", + "BindingProperty", + "ClassElement", + "AccessorProperty", + "ImportDeclarationSpecifier", + "WithClause", + "ImportAttribute", + "ImportAttributeKey", + "ExportDefaultDeclarationKind", + "ModuleExportName", + "TSEnumMemberName", + "TSLiteral", + "TSType", + "TSConditionalType", + "TSTypeOperator", + "TSArrayType", + "TSTupleType", + "TSOptionalType", + "TSRestType", + "TSTupleElement", + "TSInterfaceBody", + "TSSignature", + "TSIndexSignature", + "TSCallSignatureDeclaration", + "TSConstructSignatureDeclaration", + "TSIndexSignatureName", + "TSTypePredicate", + "TSTypePredicateName", + "TSModuleDeclarationName", + "TSModuleDeclarationBody", + "TSTypeQueryExprName", + "TSImportAttribute", + "TSImportAttributes", + "TSImportAttributeName", + "TSFunctionType", + "TSConstructorType", + "TSMappedType", + "TSModuleReference", + "TSExportAssignment", + "TSNamespaceExportDeclaration", + "JSDocNullableType", + "JSDocUnknownType", + "JSXExpression", + "JSXEmptyExpression", + "JSXAttribute", + "JSXAttributeName", + "JSXAttributeValue", + "JSXChild", + "JSXSpreadChild", +]; + +pub fn blacklist((ident, _): &(Ident, Type)) -> bool { + !BLACK_LIST.contains(&ident.to_string().as_str()) +} + +pub fn aliased_nodes() -> [(Ident, Type); 3] { + use syn::parse_quote as pq; + [ + (pq!(FinallyClause), pq!(BlockStatement<'a>)), + (pq!(ClassHeritage), pq!(Expression<'a>)), + (pq!(ExpressionArrayElement), pq!(Expression<'a>)), + ] +} + +impl Generator for AstKindGenerator { + fn name(&self) -> &'static str { + "AstKindGenerator" + } + + fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput { + let have_kinds: Vec<(Ident, Type)> = ctx + .ty_table + .iter() + .filter_map(|maybe_kind| match &*maybe_kind.borrow() { + kind @ (RType::Enum(_) | RType::Struct(_)) if kind.visitable() => { + let ident = kind.ident().unwrap().clone(); + let typ = kind.as_type().unwrap(); + Some((ident, typ)) + } + _ => None, + }) + .filter(blacklist) + .chain(aliased_nodes()) + .collect(); + + let types: Vec = + have_kinds.iter().map(|(ident, _)| parse_quote!(#ident)).collect_vec(); + + let kinds: Vec = + have_kinds.iter().map(|(ident, typ)| parse_quote!(#ident(&'a #typ))).collect_vec(); + + let span_matches: Vec = have_kinds + .iter() + .map(|(ident, _)| parse_quote!(Self :: #ident(it) => it.span())) + .collect_vec(); + + let header = generated_header!(); + + GeneratorOutput::One(quote! { + #header + + use crate::ast::*; + use oxc_span::{GetSpan, Span}; + + endl!(); + + #[derive(Debug, Clone, Copy)] + pub enum AstType { + #(#types),*, + } + + endl!(); + + /// Untyped AST Node Kind + #[derive(Debug, Clone, Copy)] + pub enum AstKind<'a> { + #(#kinds),*, + } + + endl!(); + + impl<'a> GetSpan for AstKind<'a> { + #[allow(clippy::match_same_arms)] + fn span(&self) -> Span { + match self { + #(#span_matches),*, + } + } + } + }) + } +} diff --git a/tasks/ast_codegen/src/generators/impl_get_span.rs b/tasks/ast_codegen/src/generators/impl_get_span.rs new file mode 100644 index 0000000000000..312f9020ac9a7 --- /dev/null +++ b/tasks/ast_codegen/src/generators/impl_get_span.rs @@ -0,0 +1,108 @@ +use std::collections::HashMap; + +use itertools::Itertools; +use lazy_static::lazy_static; +use proc_macro2::TokenStream; +use quote::quote; +use syn::{parse_quote, Attribute, Variant}; + +use crate::{ + schema::{REnum, RStruct, RType}, + CodegenCtx, Generator, GeneratorOutput, +}; + +use super::generated_header; + +pub struct ImplGetSpanGenerator; + +const EDGE_CASES: [&str; 1] = ["BindingPattern"]; + +fn edge_case(it: &std::cell::Ref) -> bool { + !it.ident().is_some_and(|it| EDGE_CASES.contains(&it.to_string().as_str())) +} + +fn edge_case_impls() -> TokenStream { + quote! { + endl!(); + impl<'a> GetSpan for BindingPattern<'a> { + fn span(&self) -> Span { + self.kind.span() + } + } + } +} + +impl Generator for ImplGetSpanGenerator { + fn name(&self) -> &'static str { + "ImplGetSpanGenerator" + } + + fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput { + let impls: Vec = ctx + .ty_table + .iter() + .map(|it| it.borrow()) + .filter(|it| it.visitable()) + .filter(|it| matches!(&**it, RType::Enum(_) | RType::Struct(_))) + .filter(edge_case) + .map(|kind| match &*kind { + RType::Enum(it) => impl_enum(it), + RType::Struct(it) => impl_struct(it), + _ => unreachable!("already filtered out!"), + }) + .collect(); + + let edge_impls = edge_case_impls(); + + let header = generated_header!(); + + GeneratorOutput::One(quote! { + #header + insert!("#![allow(clippy::match_same_arms)]"); + endl!(); + + use crate::ast::*; + use oxc_span::{GetSpan, Span}; + + #(#impls)* + + #edge_impls + + }) + } +} + +fn impl_enum(it @ REnum { item, .. }: &REnum) -> TokenStream { + let typ = it.as_type(); + let generics = &item.generics; + let matches: Vec = item + .variants + .iter() + .map(|Variant { ident, .. }| quote!(Self :: #ident(it) => it.span())) + .collect_vec(); + + quote! { + endl!(); + impl #generics GetSpan for #typ { + fn span(&self) -> Span { + match self { + #(#matches),* + } + } + } + } +} + +fn impl_struct(it @ RStruct { item, .. }: &RStruct) -> TokenStream { + let typ = it.as_type(); + let generics = &item.generics; + quote! { + endl!(); + impl #generics GetSpan for #typ { + #[inline] + fn span(&self) -> Span { + self.span + } + } + } +} diff --git a/tasks/ast_codegen/src/generators/mod.rs b/tasks/ast_codegen/src/generators/mod.rs new file mode 100644 index 0000000000000..f8eca3f124d3a --- /dev/null +++ b/tasks/ast_codegen/src/generators/mod.rs @@ -0,0 +1,43 @@ +mod ast; +mod ast_kind; +mod impl_get_span; + +/// Inserts a newline in the `TokenStream`. +#[allow(unused)] +macro_rules! endl { + () => { + /* only works in the context of `quote` macro family! */ + }; +} + +/// Similar to how `insert` macro works in the context of `quote` macro family, But this one can be +/// used outside and accepts expressions. +/// Wraps the result of the given expression in `insert!({value here});` and outputs it as `TokenStream`. +macro_rules! insert { + ($txt:expr) => {{ + format!(r#"insert!("{}");"#, $txt.as_str()).parse::().unwrap() + }}; +} + +/// Creates a generated file warning + required information for a generated file. +macro_rules! generated_header { + () => {{ + let file = file!().replace("\\", "/"); + let edit_comment = $crate::generators::insert!(format!( + "// To edit this generated file you have to edit `{file}`" + )); + // TODO add generation date, AST source hash, etc here. + quote::quote! { + insert!("// Auto-generated code, DO NOT EDIT DIRECTLY!"); + #edit_comment + endl!(); + } + }}; +} + +pub(crate) use generated_header; +pub(crate) use insert; + +pub use ast::AstGenerator; +pub use ast_kind::AstKindGenerator; +pub use impl_get_span::ImplGetSpanGenerator; diff --git a/tasks/ast_codegen/src/linker.rs b/tasks/ast_codegen/src/linker.rs new file mode 100644 index 0000000000000..41e46391f6950 --- /dev/null +++ b/tasks/ast_codegen/src/linker.rs @@ -0,0 +1,100 @@ +use std::collections::VecDeque; + +use super::{CodegenCtx, Cow, Inherit, Itertools, RType, Result}; + +pub trait Linker<'a> { + fn link(&'a self, linker: impl FnMut(&mut RType, &'a Self) -> Result) -> Result<&'a ()>; +} + +pub trait Unresolved { + fn unresolved(&self) -> bool; + fn resolved(&self) -> bool { + !self.unresolved() + } +} + +impl Unresolved for Inherit { + fn unresolved(&self) -> bool { + matches!(self, Self::Unlinked(_)) + } +} + +impl Unresolved for Vec { + fn unresolved(&self) -> bool { + self.iter().any(Unresolved::unresolved) + } +} + +impl<'a> Linker<'a> for CodegenCtx { + fn link( + &'a self, + mut linker: impl FnMut(&mut RType, &'a Self) -> Result, + ) -> Result<&'a ()> { + // we sort by `TypeId` so we always have the same ordering as how it is written in the rust. + let mut unresolved = self + .ident_table + .iter() + .sorted_by_key(|it| it.1) + .map(|it| it.0) + .collect::>(); + + while let Some(next) = unresolved.pop_back() { + let next_id = *self.type_id(next).unwrap(); + + let val = &mut self.ty_table[next_id].borrow_mut(); + + if !linker(val, self)? { + // for now we don't have entangled dependencies so we just add unresolved item back + // to the list so we revisit it again at the end. + unresolved.push_front(next); + } + } + Ok(&()) + } +} + +/// Returns false if can't resolve at the moment +/// # Panics +/// On invalid inheritance. +#[allow(clippy::unnecessary_wraps)] +pub fn linker(ty: &mut RType, ctx: &CodegenCtx) -> Result { + // Exit early if it isn't an enum, We only link to resolve enum inheritance! + let RType::Enum(ty) = ty else { + return Ok(true); + }; + + // Exit early if there is this enum doesn't use enum inheritance + if ty.meta.inherits.is_empty() { + return Ok(true); + } + + let inherits = ty + .meta + .inherits + .drain(..) + .map(|it| match it { + Inherit::Unlinked(ref sup) => { + let linkee = ctx.find(&Cow::Owned(sup.to_string())).unwrap(); + let variants = match &*linkee.borrow() { + RType::Enum(enum_) => { + if enum_.meta.inherits.unresolved() { + return Err(it); + } + enum_.item.variants.clone() + } + _ => { + panic!("invalid inheritance, you can only inherit from enums and in enums.") + } + }; + ty.item.variants.extend(variants.clone()); + Ok(Inherit::Linked { super_: sup.clone(), variants }) + } + Inherit::Linked { .. } => Ok(it), + }) + .collect::>>(); + let unresolved = inherits.iter().any(std::result::Result::is_err); + + ty.meta.inherits = inherits.into_iter().map(|it| it.unwrap_or_else(|it| it)).collect(); + + Ok(!unresolved) +} diff --git a/tasks/ast_codegen/src/main.rs b/tasks/ast_codegen/src/main.rs new file mode 100644 index 0000000000000..6754fa22dc1a1 --- /dev/null +++ b/tasks/ast_codegen/src/main.rs @@ -0,0 +1,260 @@ +// TODO: remove me please! +#![allow(dead_code, unused_imports)] +mod defs; +mod generators; +mod linker; +mod pprint; +mod schema; + +use std::{ + borrow::Cow, + cell::RefCell, + collections::HashMap, + fs, + io::{Read, Write}, + path::PathBuf, + rc::Rc, +}; + +use itertools::Itertools; +use pprint::pprint; +use proc_macro2::TokenStream; +use syn::parse_file; + +use defs::TypeDef; +use generators::{AstGenerator, AstKindGenerator}; +use linker::{linker, Linker}; +use schema::{Inherit, Module, REnum, RStruct, RType, Schema}; + +use crate::generators::ImplGetSpanGenerator; + +type Result = std::result::Result; +type TypeId = usize; +type TypeName = String; +type TypeTable = Vec; +type IdentTable = HashMap; +type TypeRef = Rc>; + +#[derive(Default)] +struct AstCodegen { + files: Vec, + generators: Vec>, +} + +trait Generator { + fn name(&self) -> &'static str; + fn generate(&mut self, ctx: &CodegenCtx) -> GeneratorOutput; +} + +#[derive(Debug, Clone)] +enum GeneratorOutput { + None, + One(TokenStream), + Many(HashMap), + Info(String), +} + +impl GeneratorOutput { + pub fn as_none(&self) { + assert!(matches!(self, Self::None)); + } + + pub fn as_one(&self) -> &TokenStream { + if let Self::One(it) = self { + it + } else { + panic!(); + } + } + + pub fn as_many(&self) -> &HashMap { + if let Self::Many(it) = self { + it + } else { + panic!(); + } + } + + pub fn as_info(&self) -> &String { + if let Self::Info(it) = self { + it + } else { + panic!(); + } + } +} + +struct CodegenCtx { + modules: Vec, + ty_table: TypeTable, + ident_table: IdentTable, +} + +struct CodegenResult { + /// One schema per definition file + schema: Vec, + outputs: Vec<(/* generator name */ &'static str, /* output */ GeneratorOutput)>, +} + +impl CodegenCtx { + fn new(mods: Vec) -> Self { + // worst case len + let len = mods.iter().fold(0, |acc, it| acc + it.items.len()); + let defs = mods.iter().flat_map(|it| it.items.iter()); + + let mut ty_table = TypeTable::with_capacity(len); + let mut ident_table = IdentTable::with_capacity(len); + for def in defs { + if let Some(ident) = def.borrow().ident() { + let ident = ident.to_string(); + let type_id = ty_table.len(); + ty_table.push(TypeRef::clone(def)); + ident_table.insert(ident, type_id); + } + } + Self { modules: mods, ty_table, ident_table } + } + + fn find(&self, key: &TypeName) -> Option { + self.type_id(key).map(|id| TypeRef::clone(&self.ty_table[*id])) + } + + fn type_id<'b>(&'b self, key: &'b TypeName) -> Option<&'b TypeId> { + self.ident_table.get(key) + } +} + +impl AstCodegen { + #[must_use] + fn add_file

(mut self, path: P) -> Self + where + P: AsRef, + { + self.files.push(path.as_ref().into()); + self + } + + #[must_use] + fn with(mut self, generator: G) -> Self + where + G: Generator + 'static, + { + self.generators.push(Box::new(generator)); + self + } + + fn generate(self) -> Result { + let modules = self + .files + .into_iter() + .map(Module::from) + .map(Module::load) + .map_ok(Module::expand) + .flatten() + .map_ok(Module::analyze) + .collect::>>>()??; + + let ctx = CodegenCtx::new(modules); + ctx.link(linker)?; + + let outputs = self + .generators + .into_iter() + .map(|mut gen| (gen.name(), gen.generate(&ctx))) + .collect_vec(); + + let schema = ctx.modules.into_iter().map(Module::build).collect::>>()?; + Ok(CodegenResult { schema, outputs }) + } +} + +const AST_ROOT_DIR: &str = "crates/oxc_ast"; + +fn files() -> impl std::iter::Iterator { + fn path(path: &str) -> String { + format!("{AST_ROOT_DIR}/src/ast/{path}.rs") + } + + vec![path("literal"), path("js"), path("ts"), path("jsx")].into_iter() +} + +fn output_dir() -> Result { + let dir = format!("{AST_ROOT_DIR}/src/generated"); + fs::create_dir_all(&dir).map_err(|e| e.to_string())?; + Ok(dir) +} + +#[allow(clippy::print_stdout)] +fn main() -> std::result::Result<(), Box> { + let CodegenResult { outputs, .. } = files() + .fold(AstCodegen::default(), AstCodegen::add_file) + .with(AstGenerator) + .with(AstKindGenerator) + .with(ImplGetSpanGenerator) + .generate()?; + + let output_dir = output_dir()?; + let outputs: HashMap<_, _> = outputs.into_iter().collect(); + + { + // write `span.rs` file + let output = outputs[ImplGetSpanGenerator.name()].as_one(); + let span_content = pprint(output); + + let path = format!("{output_dir}/span.rs"); + let mut file = fs::File::create(path)?; + + file.write_all(span_content.as_bytes())?; + } + + { + // write `ast_kind.rs` file + let output = outputs[AstKindGenerator.name()].as_one(); + let span_content = pprint(output); + + let path = format!("{output_dir}/ast_kind.rs"); + let mut file = fs::File::create(path)?; + + file.write_all(span_content.as_bytes())?; + } + + // NOTE: Print AstKind + // println!( + // "{}", + // outputs + // .into_iter() + // .find(|it| it.0 == AstKindGenerator.name()) + // .map(|(_, output)| { + // let GeneratorOutput::One(result) = output else { unreachable!() }; + // prettyplease::unparse(&parse_file(result.to_string().as_str()).unwrap()) + // }) + // .unwrap() + // ); + + // NOTE: Print AST + // println!( + // "{}", + // outputs + // .into_iter() + // .find(|it| it.0 == AstGenerator.name()) + // .map(|(_, output)| { + // let GeneratorOutput::Many(results) = output else { unreachable!() }; + // + // results + // .into_iter() + // .map(|(k, v)| { + // format!( + // "file \"{}\":\n{}", + // k, + // prettyplease::unparse(&parse_file(v.to_string().as_str()).unwrap()) + // ) + // }) + // .join("\n //-nextfile") + // }) + // .unwrap() + // ); + + // let schema = serde_json::to_string_pretty(&schema).map_err(|e| e.to_string())?; + // println!("{schema}"); + Ok(()) +} diff --git a/tasks/ast_codegen/src/pprint.rs b/tasks/ast_codegen/src/pprint.rs new file mode 100644 index 0000000000000..040db30f8452d --- /dev/null +++ b/tasks/ast_codegen/src/pprint.rs @@ -0,0 +1,48 @@ +use lazy_static::lazy_static; +use proc_macro2::TokenStream; +use regex::{Captures, Regex, Replacer}; +use syn::parse_file; + +static INSERT_MACRO_IDENT: &str = "insert"; +static INSERT_MACRO_IDENT_LEN: usize = INSERT_MACRO_IDENT.len(); + +static ENDL_MACRO_IDENT: &str = "endl"; +static ENDL_MACRO_IDENT_LEN: usize = ENDL_MACRO_IDENT.len(); + +struct InsertReplacer; + +impl Replacer for InsertReplacer { + fn replace_append(&mut self, caps: &Captures, dst: &mut String) { + assert_eq!(caps.len(), 2); + let arg = caps.get(1); + if let Some(arg) = arg { + dst.push_str(arg.as_str()); + } + } +} + +struct EndlReplacer; + +impl Replacer for EndlReplacer { + fn replace_append(&mut self, _: &Captures, _: &mut String) {} +} + +pub fn pprint(input: &TokenStream) -> String { + lazy_static! { + static ref INSERT_REGEX: Regex = Regex::new( + format!(r#"(?m)^{INSERT_MACRO_IDENT}!\([\n\s\S]*?\"([\s\S]*?)\"[\n\s\S]*?\);$"#) + .as_str() + ) + .unwrap(); + }; + + lazy_static! { + static ref ENDL_REGEX: Regex = + Regex::new(format!(r"{ENDL_MACRO_IDENT}!\(\);").as_str()).unwrap(); + }; + + let result = prettyplease::unparse(&parse_file(input.to_string().as_str()).unwrap()); + let result = ENDL_REGEX.replace_all(&result, EndlReplacer); + let result = INSERT_REGEX.replace_all(&result, InsertReplacer).to_string(); + result +} diff --git a/tasks/ast_codegen/src/schema.rs b/tasks/ast_codegen/src/schema.rs new file mode 100644 index 0000000000000..c478004600216 --- /dev/null +++ b/tasks/ast_codegen/src/schema.rs @@ -0,0 +1,353 @@ +use proc_macro2::TokenStream; +use quote::{ToTokens, TokenStreamExt}; +use syn::{ + braced, + parse::{Parse, ParseBuffer}, + parse_quote, + punctuated::Punctuated, + Attribute, Generics, Ident, Item, ItemConst, ItemEnum, ItemMacro, ItemStruct, ItemUse, Token, + Type, Variant, Visibility, +}; + +use crate::TypeName; + +use super::{parse_file, Itertools, PathBuf, Rc, Read, RefCell, Result, TypeDef, TypeRef}; + +#[derive(Debug, serde::Serialize)] +pub struct Schema { + source: PathBuf, + definitions: Definitions, +} + +#[derive(Debug, serde::Serialize)] +pub struct Definitions { + types: Vec, +} + +#[derive(Debug, Clone)] +pub enum Inherit { + Unlinked(String), + Linked { super_: String, variants: Punctuated }, +} + +impl From for Inherit { + fn from(ident: Ident) -> Self { + Self::Unlinked(ident.to_string()) + } +} + +#[derive(Debug, Default, Clone)] +pub struct EnumMeta { + pub inherits: Vec, + pub visitable: bool, +} + +#[derive(Debug)] +pub struct REnum { + pub item: ItemEnum, + pub meta: EnumMeta, +} + +impl REnum { + pub fn with_meta(item: ItemEnum, meta: EnumMeta) -> Self { + Self { item, meta } + } + + pub fn ident(&self) -> &Ident { + &self.item.ident + } + + pub fn as_type(&self) -> Type { + let ident = self.ident(); + let generics = &self.item.generics; + parse_quote!(#ident #generics) + } +} + +impl From for REnum { + fn from(item: ItemEnum) -> Self { + Self { item, meta: EnumMeta::default() } + } +} + +/// Placeholder for now! +#[derive(Debug, Default, Clone)] +pub struct StructMeta { + pub visitable: bool, +} + +#[derive(Debug)] +pub struct RStruct { + pub item: ItemStruct, + pub meta: StructMeta, +} + +impl RStruct { + pub fn ident(&self) -> &Ident { + &self.item.ident + } + + pub fn as_type(&self) -> Type { + let ident = self.ident(); + let generics = &self.item.generics; + parse_quote!(#ident #generics) + } +} + +impl From for RStruct { + fn from(item: ItemStruct) -> Self { + Self { item, meta: StructMeta::default() } + } +} + +#[derive(Debug)] +pub enum RType { + Enum(REnum), + Struct(RStruct), + + Use(ItemUse), + Const(ItemConst), + Macro(ItemMacro), +} + +impl ToTokens for RType { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::Enum(it) => it.item.to_tokens(tokens), + Self::Struct(it) => it.item.to_tokens(tokens), + + Self::Use(it) => it.to_tokens(tokens), + Self::Const(it) => it.to_tokens(tokens), + Self::Macro(it) => it.to_tokens(tokens), + } + } +} + +impl RType { + pub fn ident(&self) -> Option<&Ident> { + match self { + RType::Enum(ty) => Some(ty.ident()), + RType::Struct(ty) => Some(ty.ident()), + + RType::Use(_) => None, + RType::Macro(tt) => tt.ident.as_ref(), + RType::Const(tt) => Some(&tt.ident), + } + } + + pub fn as_type(&self) -> Option { + match self { + RType::Enum(it) => Some(it.as_type()), + RType::Struct(it) => Some(it.as_type()), + _ => None, + } + } + + pub fn visitable(&self) -> bool { + match self { + RType::Enum(it) => it.meta.visitable, + RType::Struct(it) => it.meta.visitable, + _ => false, + } + } + + pub fn set_visitable(&mut self, value: bool) -> Result<()> { + match self { + RType::Enum(it) => it.meta.visitable = value, + RType::Struct(it) => it.meta.visitable = value, + _ => return Err("Unsupported type!".to_string()), + } + Ok(()) + } +} + +impl TryFrom for RType { + type Error = String; + fn try_from(item: Item) -> Result { + match item { + Item::Enum(it) => Ok(RType::Enum(it.into())), + Item::Struct(it) => Ok(RType::Struct(it.into())), + Item::Macro(it) => Ok(RType::Macro(it)), + Item::Use(it) => Ok(RType::Use(it)), + Item::Const(it) => Ok(RType::Const(it)), + _ => Err(String::from("Unsupported Item!")), + } + } +} + +const LOAD_ERROR: &str = "should be loaded by now!"; +#[derive(Debug)] +pub struct Module { + pub path: PathBuf, + #[allow(clippy::struct_field_names)] + pub module: TypeName, + pub shebang: Option, + pub attrs: Vec, + pub items: Vec, + pub loaded: bool, +} + +impl ToTokens for Module { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(self.attrs.clone()); + self.items.iter().for_each(|it| it.borrow().to_tokens(tokens)); + } +} + +impl Module { + pub fn with_path(path: PathBuf) -> Self { + let module = path.file_stem().map(|it| it.to_string_lossy().to_string()).unwrap(); + Self { path, module, shebang: None, attrs: Vec::new(), items: Vec::new(), loaded: false } + } + + pub fn load(mut self) -> Result { + assert!(!self.loaded, "can't load twice!"); + + let mut file = std::fs::File::open(&self.path).map_err(|e| e.to_string())?; + let mut content = String::new(); + file.read_to_string(&mut content).map_err(|e| e.to_string())?; + let file = parse_file(content.as_str()).map_err(|e| e.to_string())?; + self.shebang = file.shebang; + self.attrs = file.attrs; + self.items = file + .items + .into_iter() + .filter(|it| match it { + Item::Enum(_) | Item::Struct(_) | Item::Use(_) | Item::Const(_) => true, + // These contain enums with inheritance + Item::Macro(m) if m.mac.path.is_ident("inherit_variants") => true, + _ => false, + }) + .map(TryInto::try_into) + .map_ok(|it| Rc::new(RefCell::new(it))) + .collect::>()?; + self.loaded = true; + Ok(self) + } + + /// Expand `inherit_variants` macros to their inner enum. + /// This would also populate `inherits` field of `EnumMeta` types. + pub fn expand(self) -> Result { + if !self.loaded { + return Err(String::from(LOAD_ERROR)); + } + + self.items.iter().try_for_each(expand)?; + Ok(self) + } + + /// Fills the Meta types. + pub fn analyze(self) -> Result { + if !self.loaded { + return Err(String::from(LOAD_ERROR)); + } + + self.items.iter().try_for_each(analyze)?; + Ok(self) + } + + pub fn build(self) -> Result { + if !self.loaded { + return Err(String::from(LOAD_ERROR)); + } + + let definitions = Definitions { + // We filter map to get rid of stuff we don't need in our schema. + types: self.items.into_iter().filter_map(|it| (&*it.borrow()).into()).collect(), + }; + Ok(Schema { source: self.path, definitions }) + } +} + +pub fn expand(type_def: &TypeRef) -> Result<()> { + let to_replace = match &*type_def.borrow() { + RType::Macro(mac) => { + let (enum_, inherits) = mac + .mac + .parse_body_with(|input: &ParseBuffer| { + // Because of `@inherit`s we can't use the actual `ItemEnum` parse, + // This closure is similar to how `ItemEnum` parser works, With the exception + // of how we approach our variants, First we try to parse a variant out of our + // tokens if we fail we try parsing the inheritance, And we would raise an + // error only if both of these fail. + let attrs = input.call(Attribute::parse_outer)?; + let vis = input.parse::()?; + let enum_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, brace_token, variants, inherits) = { + let where_clause = input.parse()?; + + let content; + let brace = braced!(content in input); + let mut variants = Punctuated::new(); + let mut inherits = Vec::::new(); + while !content.is_empty() { + if let Ok(variant) = Variant::parse(&content) { + variants.push_value(variant); + let punct = content.parse()?; + variants.push_punct(punct); + } else if content.parse::().is_ok() + && content.parse::().is_ok_and(|id| id == "inherit") + { + inherits.push(content.parse::()?); + } else { + panic!("Invalid inherit_variants usage!"); + } + } + + (where_clause, brace, variants, inherits) + }; + Ok(( + ItemEnum { + attrs, + vis, + enum_token, + ident, + generics: Generics { where_clause, ..generics }, + brace_token, + variants, + }, + inherits, + )) + }) + .map_err(|e| e.to_string())?; + Some(RType::Enum(REnum::with_meta( + enum_, + EnumMeta { + inherits: inherits.into_iter().map(Into::into).collect(), + ..EnumMeta::default() + }, + ))) + } + _ => None, + }; + + if let Some(to_replace) = to_replace { + *type_def.borrow_mut() = to_replace; + } + + Ok(()) +} + +pub fn analyze(type_def: &TypeRef) -> Result<()> { + let is_visitable = match &*type_def.borrow() { + RType::Enum(REnum { item: ItemEnum { attrs, .. }, .. }) + | RType::Struct(RStruct { item: ItemStruct { attrs, .. }, .. }) => { + Some(attrs.iter().any(|attr| attr.path().is_ident("visited_node"))) + } + _ => None, + }; + + if let Some(is_visitable) = is_visitable { + type_def.borrow_mut().set_visitable(is_visitable)?; + } + + Ok(()) +} + +impl From for Module { + fn from(path: PathBuf) -> Self { + Self::with_path(path) + } +} diff --git a/tasks/coverage/parser_babel.snap b/tasks/coverage/parser_babel.snap index 20c5cde9b58f0..72b8947dd83f9 100644 --- a/tasks/coverage/parser_babel.snap +++ b/tasks/coverage/parser_babel.snap @@ -3,7 +3,7 @@ commit: 12619ffe parser_babel Summary: AST Parsed : 2095/2101 (99.71%) Positive Passed: 2087/2101 (99.33%) -Negative Passed: 1364/1501 (90.87%) +Negative Passed: 1365/1501 (90.94%) Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js" @@ -27,7 +27,6 @@ Expect Syntax Error: "es2015/uncategorised/297/input.js" Expect Syntax Error: "es2015/uncategorised/335/input.js" Expect Syntax Error: "es2017/async-functions/async-await-as-arrow-binding-identifier/input.js" Expect Syntax Error: "es2017/async-functions/await-binding-inside-arrow-params-inside-async-arrow-params/input.js" -Expect Syntax Error: "es2017/trailing-function-commas/7/input.js" Expect Syntax Error: "es2018/object-rest-spread/24/input.js" Expect Syntax Error: "es2018/object-rest-spread/comma-after-rest/input.js" Expect Syntax Error: "es2018/object-rest-spread/comma-after-spread-for-in/input.js" @@ -5154,6 +5153,12 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts" · ─ ╰──── + × Unexpected token + ╭─[es2017/trailing-function-commas/7/input.js:1:8] + 1 │ ('foo',) + · ─ + ╰──── + × Expected `(` but found `await` ╭─[es2018/async-generators/for-await-async-context/input.js:2:7] 1 │ function f() { diff --git a/tasks/coverage/parser_typescript.snap b/tasks/coverage/parser_typescript.snap index 19c29d9fda329..aa0e4e073c930 100644 --- a/tasks/coverage/parser_typescript.snap +++ b/tasks/coverage/parser_typescript.snap @@ -3999,20 +3999,18 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── - × Expected `)` but found `Identifier` - ╭─[compiler/ParameterList5.ts:1:23] + × A parameter property is only allowed in a constructor implementation. + ╭─[compiler/ParameterList5.ts:1:16] 1 │ function A(): (public B) => C { - · ┬ - · ╰── `)` expected + · ──────── 2 │ } ╰──── - × Expected `)` but found `Identifier` - ╭─[compiler/ParameterList6.ts:2:26] + × A parameter property is only allowed in a constructor implementation. + ╭─[compiler/ParameterList6.ts:2:19] 1 │ class C { 2 │ constructor(C: (public A) => any) { - · ┬ - · ╰── `)` expected + · ──────── 3 │ } ╰──── @@ -15431,11 +15429,11 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── × Unexpected token - ╭─[conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts:16:2] - 15 │ // Missing the first operand - 16 │ (, ANY); - · ─ - 17 │ (, BOOLEAN); + ╭─[conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts:9:7] + 8 │ // Missing the second operand + 9 │ (ANY, ); + · ─ + 10 │ (BOOLEAN, ); ╰──── × 'with' statements are not allowed @@ -15952,13 +15950,12 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" · ─ ╰──── - × Expected `>` but found `,` - ╭─[conformance/externalModules/topLevelAwaitErrors.1.ts:5:14] + × Unexpected token + ╭─[conformance/externalModules/topLevelAwaitErrors.1.ts:4:10] + 3 │ // reparse call as invalid await should error 4 │ await (1,); + · ─ 5 │ await (1); - · ┬ - · ╰── `>` expected - 6 │ ╰──── × Cannot use `await` as an identifier in an async context @@ -17726,20 +17723,18 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── - × Expected `)` but found `Identifier` - ╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList5.ts:1:23] + × A parameter property is only allowed in a constructor implementation. + ╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList5.ts:1:16] 1 │ function A(): (public B) => C { - · ┬ - · ╰── `)` expected + · ──────── 2 │ } ╰──── - × Expected `)` but found `Identifier` - ╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList6.ts:2:26] + × A parameter property is only allowed in a constructor implementation. + ╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList6.ts:2:19] 1 │ class C { 2 │ constructor(C: (public A) => any) { - · ┬ - · ╰── `)` expected + · ──────── 3 │ } ╰──── diff --git a/tasks/website/src/linter/snapshots/cli.snap b/tasks/website/src/linter/snapshots/cli.snap index ed6c20c08e058..23397ef38ef75 100644 --- a/tasks/website/src/linter/snapshots/cli.snap +++ b/tasks/website/src/linter/snapshots/cli.snap @@ -58,6 +58,8 @@ Arguments: Enable the experimental jsdoc plugin and detect JSDoc problems - **` --jest-plugin`** — Enable the Jest plugin and detect test problems +- **` --vitest-plugin`** — + Enable the Vitest plugin and detect test problems - **` --jsx-a11y-plugin`** — Enable the JSX-a11y plugin and detect accessibility problems - **` --nextjs-plugin`** — diff --git a/tasks/website/src/linter/snapshots/cli_terminal.snap b/tasks/website/src/linter/snapshots/cli_terminal.snap index 511faceabbb29..42246aa3a568c 100644 --- a/tasks/website/src/linter/snapshots/cli_terminal.snap +++ b/tasks/website/src/linter/snapshots/cli_terminal.snap @@ -35,6 +35,7 @@ Enable Plugins recommended to use along side with the `--tsconfig` option. --jsdoc-plugin Enable the experimental jsdoc plugin and detect JSDoc problems --jest-plugin Enable the Jest plugin and detect test problems + --vitest-plugin Enable the Vitest plugin and detect test problems --jsx-a11y-plugin Enable the JSX-a11y plugin and detect accessibility problems --nextjs-plugin Enable the Next.js plugin and detect Next.js problems --react-perf-plugin Enable the React performance plugin and detect rendering performance