From a48ebd62954559af9350a898ead477c7c1c74c44 Mon Sep 17 00:00:00 2001 From: dalaoshu <laipichan@qq.com> Date: Fri, 15 Nov 2024 00:08:04 +0800 Subject: [PATCH 01/27] fix(tasks): cargo clippy error on rust 1.82.0 (#7283) I mentioned this clippy issue in the discord help channel. The problem seems to be related to using the stable rust toolchain, but when I switched to version `1.81.0`, the issue was resolved. However, some of the clippy suggestions might still be worth considering and could be adopted. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- tasks/ast_tools/src/generators/typescript.rs | 14 ++++++++------ tasks/ast_tools/src/layout.rs | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tasks/ast_tools/src/generators/typescript.rs b/tasks/ast_tools/src/generators/typescript.rs index 8baae4f4c8baf8..bcad09ef3f690e 100644 --- a/tasks/ast_tools/src/generators/typescript.rs +++ b/tasks/ast_tools/src/generators/typescript.rs @@ -108,17 +108,19 @@ fn typescript_struct(def: &StructDef, always_flatten_structs: &FxHashSet<TypeId> let ident = field.ident().unwrap(); if let Some(append_after) = append_to.get(&ident.to_string()) { - let after_type = match &append_after.markers.derive_attributes.estree.typescript_type { - Some(ty) => ty.clone(), - None => { + let after_type = + if let Some(ty) = &append_after.markers.derive_attributes.estree.typescript_type { + ty.clone() + } else { let typ = append_after.typ.name(); if let TypeName::Opt(inner) = typ { type_to_string(inner) } else { - panic!("expected field labeled with append_to to be Option<...>, but found {typ}"); + panic!( + "expected field labeled with append_to to be Option<...>, but found {typ}" + ); } - } - }; + }; if let Some(inner) = ty.strip_prefix("Array<") { ty = format!("Array<{after_type} | {inner}"); } else { diff --git a/tasks/ast_tools/src/layout.rs b/tasks/ast_tools/src/layout.rs index e380056e642cb1..1c6a8a315fa673 100644 --- a/tasks/ast_tools/src/layout.rs +++ b/tasks/ast_tools/src/layout.rs @@ -160,10 +160,10 @@ impl Layout { /// For `n` bigger than `16`, Or if it's not a power of 2 number fn max_val_of_bytes(n: usize) -> u128 { match n { - 1 => u8::MAX as u128, - 2 => u16::MAX as u128, - 4 => u32::MAX as u128, - 8 => u64::MAX as u128, + 1 => u128::from(u8::MAX), + 2 => u128::from(u16::MAX), + 4 => u128::from(u32::MAX), + 8 => u128::from(u64::MAX), 16 => u128::MAX, _ => panic!("We do not support `n` bigger than 16 bytes."), } From e219ae8c94af32c5a754eee1b082a38e7f095287 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:17:21 +0000 Subject: [PATCH 02/27] docs(transformer/nullish-coalescing): clarify doc comment (#7268) Expand doc comment for `create_conditional_expression` to clarify what it does. --- .../src/es2020/nullish_coalescing_operator.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 2224b94d28c7b2..0c2090e1d4d818 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -150,18 +150,25 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { } } - /// Create a conditional expression + /// Create a conditional expression. /// /// ```js /// // Input - /// bar ?? "qux" + /// foo = bar ?? "qux" /// /// // Output - /// qux = bar !== null && bar !== void 0 ? bar : "qux" - /// // ^^^ assignment ^^^ reference ^^^ default + /// foo = bar !== null && bar !== void 0 ? bar : "qux" + /// // ^^^ assignment ^^^ reference ^^^^^ default /// ``` /// - /// reference and assignment are the same in this case, but they can be different + /// ```js + /// // Input + /// foo = bar.x ?? "qux" + /// + /// // Output + /// foo = (_bar$x = bar.x) !== null && _bar$x !== void 0 ? _bar$x : "qux" + /// // ^^^^^^^^^^^^^^^^ assignment ^^^^^^ reference ^^^^^ default + /// ``` fn create_conditional_expression( reference: Expression<'a>, assignment: Expression<'a>, From 5b5c8a9bdb93a0e056073606f912cee3a0d4b31c Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:17:22 +0000 Subject: [PATCH 03/27] fix(transformer/nullish-coalescing): correct span (#7269) Transformed expression inherit same `Span` as the input. --- .../src/es2020/nullish_coalescing_operator.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 0c2090e1d4d818..90fb82a7afb081 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -67,6 +67,7 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { Self::clone_expression(&logical_expr.left, ctx), logical_expr.left, logical_expr.right, + logical_expr.span, ctx, ); return; @@ -98,8 +99,13 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { binding.create_read_write_target(ctx), logical_expr.left, ); - let mut new_expr = - Self::create_conditional_expression(reference, assignment, logical_expr.right, ctx); + let mut new_expr = Self::create_conditional_expression( + reference, + assignment, + logical_expr.right, + logical_expr.span, + ctx, + ); if is_parent_formal_parameter { // Replace `function (a, x = a.b ?? c) {}` to `function (a, x = (() => a.b ?? c)() ){}` @@ -173,6 +179,7 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { reference: Expression<'a>, assignment: Expression<'a>, default: Expression<'a>, + span: Span, ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let op = BinaryOperator::StrictInequality; @@ -186,6 +193,6 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { ); let test = ctx.ast.expression_logical(SPAN, left, LogicalOperator::And, right); - ctx.ast.expression_conditional(SPAN, test, reference, default) + ctx.ast.expression_conditional(span, test, reference, default) } } From 345fbb9da349c7983c6d125c358f84a468bcbe73 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:17:23 +0000 Subject: [PATCH 04/27] refactor(transformer/nullish-coalescing): avoid repeated symbol lookups (#7272) `clone_expression` was unnecessarily looking up the `SymbolId` of references multiple times. Use `BoundIdentifier` instead to avoid that. Notes: * `create_conditional_expression` has to take all parts as `Expression`s just to support `this ?? something`. * `TraverseCtx::is_static` also handles `Super`, but can skip that in this case as `super ?? something` is not valid syntax. --- .../src/es2020/nullish_coalescing_operator.rs | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 90fb82a7afb081..d349134c8e6504 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -28,12 +28,11 @@ //! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-nullish-coalescing-operator> //! * Nullish coalescing TC39 proposal: <https://github.com/tc39-transfer/proposal-nullish-coalescing> -use oxc_allocator::CloneIn; use oxc_ast::{ast::*, NONE}; -use oxc_semantic::{ReferenceFlags, ScopeFlags, SymbolFlags}; +use oxc_semantic::{ScopeFlags, SymbolFlags}; use oxc_span::SPAN; use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator}; -use oxc_traverse::{Ancestor, MaybeBoundIdentifier, Traverse, TraverseCtx}; +use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx}; use crate::TransformCtx; @@ -61,16 +60,41 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { _ => unreachable!(), }; - // skip creating extra reference when `left` is static - if ctx.is_static(&logical_expr.left) { - *expr = Self::create_conditional_expression( - Self::clone_expression(&logical_expr.left, ctx), - logical_expr.left, - logical_expr.right, - logical_expr.span, - ctx, - ); - return; + // Skip creating extra reference when `left` is static + match &logical_expr.left { + Expression::ThisExpression(this) => { + let this_span = this.span; + *expr = Self::create_conditional_expression( + logical_expr.left, + ctx.ast.expression_this(this_span), + ctx.ast.expression_this(this_span), + logical_expr.right, + logical_expr.span, + ctx, + ); + return; + } + Expression::Identifier(ident) => { + let symbol_id = ctx.symbols().get_reference(ident.reference_id()).symbol_id(); + if let Some(symbol_id) = symbol_id { + // Check binding is not mutated. + // TODO(improve-on-babel): Remove this check. Whether binding is mutated or not is not relevant. + if ctx.symbols().get_resolved_references(symbol_id).all(|r| !r.is_write()) { + let binding = BoundIdentifier::new(ident.name.clone(), symbol_id); + let ident_span = ident.span; + *expr = Self::create_conditional_expression( + logical_expr.left, + binding.create_spanned_read_expression(ident_span, ctx), + binding.create_spanned_read_expression(ident_span, ctx), + logical_expr.right, + logical_expr.span, + ctx, + ); + return; + } + } + } + _ => {} } // ctx.ancestor(0) is AssignmentPattern @@ -92,7 +116,6 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { SymbolFlags::FunctionScopedVariable, ); - let reference = binding.create_read_expression(ctx); let assignment = ctx.ast.expression_assignment( SPAN, AssignmentOperator::Assign, @@ -100,8 +123,9 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { logical_expr.left, ); let mut new_expr = Self::create_conditional_expression( - reference, assignment, + binding.create_read_expression(ctx), + binding.create_read_expression(ctx), logical_expr.right, logical_expr.span, ctx, @@ -146,16 +170,6 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { } impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { - fn clone_expression(expr: &Expression<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> { - match expr { - Expression::Identifier(ident) => { - let binding = MaybeBoundIdentifier::from_identifier_reference(ident, ctx); - binding.create_spanned_expression(ident.span, ReferenceFlags::Read, ctx) - } - _ => expr.clone_in(ctx.ast.allocator), - } - } - /// Create a conditional expression. /// /// ```js @@ -164,7 +178,8 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { /// /// // Output /// foo = bar !== null && bar !== void 0 ? bar : "qux" - /// // ^^^ assignment ^^^ reference ^^^^^ default + /// // ^^^ assignment ^^^ reference1 ^^^^^ default + /// // ^^^ reference2 /// ``` /// /// ```js @@ -173,11 +188,13 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { /// /// // Output /// foo = (_bar$x = bar.x) !== null && _bar$x !== void 0 ? _bar$x : "qux" - /// // ^^^^^^^^^^^^^^^^ assignment ^^^^^^ reference ^^^^^ default + /// // ^^^^^^^^^^^^^^^^ assignment ^^^^^^ reference1 ^^^^^ default + /// // ^^^^^^ reference2 /// ``` fn create_conditional_expression( - reference: Expression<'a>, assignment: Expression<'a>, + reference1: Expression<'a>, + reference2: Expression<'a>, default: Expression<'a>, span: Span, ctx: &mut TraverseCtx<'a>, @@ -185,14 +202,9 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { let op = BinaryOperator::StrictInequality; let null = ctx.ast.expression_null_literal(SPAN); let left = ctx.ast.expression_binary(SPAN, assignment, op, null); - let right = ctx.ast.expression_binary( - SPAN, - Self::clone_expression(&reference, ctx), - op, - ctx.ast.void_0(SPAN), - ); + let right = ctx.ast.expression_binary(SPAN, reference1, op, ctx.ast.void_0(SPAN)); let test = ctx.ast.expression_logical(SPAN, left, LogicalOperator::And, right); - ctx.ast.expression_conditional(span, test, reference, default) + ctx.ast.expression_conditional(span, test, reference2, default) } } From 9f5ae5681062cf53bd5570eab807dac035b4ef88 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:17:23 +0000 Subject: [PATCH 05/27] refactor(transformer/nullish-coalescing): split main logic into separate function (#7273) Small refactor. Move main logic of the transform into a separate function, to allow `enter_expression` to be inlined. --- .../src/es2020/nullish_coalescing_operator.rs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index d349134c8e6504..50dc3b59499418 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -28,6 +28,7 @@ //! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-nullish-coalescing-operator> //! * Nullish coalescing TC39 proposal: <https://github.com/tc39-transfer/proposal-nullish-coalescing> +use oxc_allocator::Box as ArenaBox; use oxc_ast::{ast::*, NONE}; use oxc_semantic::{ScopeFlags, SymbolFlags}; use oxc_span::SPAN; @@ -55,16 +56,27 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { } // Take ownership of the `LogicalExpression` - let logical_expr = match ctx.ast.move_expression(expr) { - Expression::LogicalExpression(logical_expr) => logical_expr.unbox(), - _ => unreachable!(), + let Expression::LogicalExpression(logical_expr) = ctx.ast.move_expression(expr) else { + unreachable!() }; + *expr = self.transform_logical_expression(logical_expr, ctx); + } +} + +impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { + fn transform_logical_expression( + &mut self, + logical_expr: ArenaBox<'a, LogicalExpression<'a>>, + ctx: &mut TraverseCtx<'a>, + ) -> Expression<'a> { + let logical_expr = logical_expr.unbox(); + // Skip creating extra reference when `left` is static match &logical_expr.left { Expression::ThisExpression(this) => { let this_span = this.span; - *expr = Self::create_conditional_expression( + return Self::create_conditional_expression( logical_expr.left, ctx.ast.expression_this(this_span), ctx.ast.expression_this(this_span), @@ -72,7 +84,6 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { logical_expr.span, ctx, ); - return; } Expression::Identifier(ident) => { let symbol_id = ctx.symbols().get_reference(ident.reference_id()).symbol_id(); @@ -82,7 +93,7 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { if ctx.symbols().get_resolved_references(symbol_id).all(|r| !r.is_write()) { let binding = BoundIdentifier::new(ident.name.clone(), symbol_id); let ident_span = ident.span; - *expr = Self::create_conditional_expression( + return Self::create_conditional_expression( logical_expr.left, binding.create_spanned_read_expression(ident_span, ctx), binding.create_spanned_read_expression(ident_span, ctx), @@ -90,7 +101,6 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { logical_expr.span, ctx, ); - return; } } } @@ -165,11 +175,9 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> { self.ctx.var_declarations.insert_var(&binding, None, ctx); } - *expr = new_expr; + new_expr } -} -impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { /// Create a conditional expression. /// /// ```js From b57d00d6fbb501b275a2c7ecb10742b4b4d70449 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:36:16 +0000 Subject: [PATCH 06/27] fix(tasks/compat_data): fix misplaced features (#7284) closes #7279 --- crates/oxc_transformer/src/options/env.rs | 4 +- .../src/options/es_features.rs | 688 +++++++------- .../tests/integrations/es_target.rs | 2 +- tasks/compat_data/data.json | 852 +++++++++--------- tasks/compat_data/es-features.js | 258 +++--- 5 files changed, 902 insertions(+), 902 deletions(-) diff --git a/crates/oxc_transformer/src/options/env.rs b/crates/oxc_transformer/src/options/env.rs index dbc88013e43ca3..ba159d7de7dc10 100644 --- a/crates/oxc_transformer/src/options/env.rs +++ b/crates/oxc_transformer/src/options/env.rs @@ -176,14 +176,14 @@ impl From<EngineTargets> for EnvOptions { async_generator_functions: o.has_feature(ES2018AsyncGeneratorFunctions), }, es2019: ES2019Options { - optional_catch_binding: o.has_feature(ES2018OptionalCatchBinding), + optional_catch_binding: o.has_feature(ES2019OptionalCatchBinding), }, es2020: ES2020Options { nullish_coalescing_operator: o.has_feature(ES2020NullishCoalescingOperator), big_int: o.has_feature(ES2020BigInt), }, es2021: ES2021Options { - logical_assignment_operators: o.has_feature(ES2020LogicalAssignmentOperators), + logical_assignment_operators: o.has_feature(ES2021LogicalAssignmentOperators), }, es2022: ES2022Options { class_static_block: o.has_feature(ES2022ClassStaticBlock), diff --git a/crates/oxc_transformer/src/options/es_features.rs b/crates/oxc_transformer/src/options/es_features.rs index 9d3b05460c43cc..b0ef10a550515f 100644 --- a/crates/oxc_transformer/src/options/es_features.rs +++ b/crates/oxc_transformer/src/options/es_features.rs @@ -6,53 +6,53 @@ use rustc_hash::FxHashMap; use std::sync::OnceLock; #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub enum ESFeature { - ES5ReservedWords, - ES5PropertyLiterals, ES5MemberExpressionLiterals, + ES5PropertyLiterals, + ES5ReservedWords, ES2015Parameters, - ES2015Regenerator, - ES2015NewTarget, - ES2015TypeofSymbol, - ES2015BlockScoping, - ES2015Destructuring, - ES2015Spread, - ES2015UnicodeRegex, - ES2015UnicodeEscapes, - ES2015StickyRegex, - ES2015ForOf, - ES2015ComputedProperties, - ES2015DuplicateKeys, - ES2015ShorthandProperties, - ES2015ObjectSuper, - ES2015Classes, - ES2015BlockScopedFunctions, - ES2015ArrowFunctions, - ES2015FunctionName, - ES2015Literals, ES2015TemplateLiterals, + ES2015Literals, + ES2015FunctionName, + ES2015ArrowFunctions, + ES2015BlockScopedFunctions, + ES2015Classes, + ES2015ObjectSuper, + ES2015ShorthandProperties, + ES2015DuplicateKeys, + ES2015ComputedProperties, + ES2015ForOf, + ES2015StickyRegex, + ES2015UnicodeEscapes, + ES2015UnicodeRegex, + ES2015Spread, + ES2015Destructuring, + ES2015BlockScoping, + ES2015TypeofSymbol, + ES2015NewTarget, + ES2015Regenerator, ES2016ExponentiationOperator, ES2017AsyncToGenerator, - ES2018NamedCapturingGroupsRegex, - ES2018UnicodePropertyRegex, + ES2018AsyncGeneratorFunctions, + ES2018ObjectRestSpread, ES2018DotallRegex, + ES2018UnicodePropertyRegex, + ES2018NamedCapturingGroupsRegex, ES2018LookbehindRegex, - ES2018ObjectRestSpread, - ES2018AsyncGeneratorFunctions, - ES2018OptionalCatchBinding, ES2019JsonStrings, - ES2019OptionalChaining, + ES2019OptionalCatchBinding, ES2020NullishCoalescingOperator, - ES2020LogicalAssignmentOperators, + ES2020OptionalChaining, ES2020BigInt, ES2021NumericSeparator, - ES2022PrivateMethods, - ES2022ClassProperties, - ES2022PrivatePropertyInObject, + ES2021LogicalAssignmentOperators, ES2022ClassStaticBlock, + ES2022PrivatePropertyInObject, + ES2022ClassProperties, + ES2022PrivateMethods, ES2022MatchIndicesRegex, ES2024UnicodeSetsRegex, - ES2025RegexpModifiers, ES2025DuplicateNamedCapturingGroupsRegex, + ES2025RegexpModifiers, } pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { use ESFeature::*; @@ -61,20 +61,20 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { FEATURES.get_or_init(|| { FxHashMap::from_iter([ ( - ES5ReservedWords, + ES5MemberExpressionLiterals, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(13u32, 0u32, 0u32)), - (Safari, Version(3u32, 1u32, 0u32)), - (OperaMobile, Version(10u32, 1u32, 0u32)), + (Chrome, Version(7u32, 0u32, 0u32)), + (Safari, Version(5u32, 1u32, 0u32)), + (OperaMobile, Version(12u32, 0u32, 0u32)), (Samsung, Version(1u32, 0u32, 0u32)), (Rhino, Version(1u32, 7u32, 13u32)), - (Node, Version(0u32, 6u32, 0u32)), + (Node, Version(0u32, 4u32, 0u32)), (Ie, Version(9u32, 0u32, 0u32)), (Firefox, Version(2u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Android, Version(4u32, 4u32, 0u32)), + (Android, Version(4u32, 0u32, 0u32)), (Electron, Version(0u32, 20u32, 0u32)), - (Opera, Version(10u32, 50u32, 0u32)), + (Opera, Version(12u32, 0u32, 0u32)), (Ios, Version(6u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(5u32, 0, 0)), @@ -101,20 +101,20 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES5MemberExpressionLiterals, + ES5ReservedWords, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(7u32, 0u32, 0u32)), - (Safari, Version(5u32, 1u32, 0u32)), - (OperaMobile, Version(12u32, 0u32, 0u32)), + (Chrome, Version(13u32, 0u32, 0u32)), + (Safari, Version(3u32, 1u32, 0u32)), + (OperaMobile, Version(10u32, 1u32, 0u32)), (Samsung, Version(1u32, 0u32, 0u32)), (Rhino, Version(1u32, 7u32, 13u32)), - (Node, Version(0u32, 4u32, 0u32)), + (Node, Version(0u32, 6u32, 0u32)), (Ie, Version(9u32, 0u32, 0u32)), (Firefox, Version(2u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Android, Version(4u32, 0u32, 0u32)), + (Android, Version(4u32, 4u32, 0u32)), (Electron, Version(0u32, 20u32, 0u32)), - (Opera, Version(12u32, 0u32, 0u32)), + (Opera, Version(10u32, 50u32, 0u32)), (Ios, Version(6u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(5u32, 0, 0)), @@ -138,76 +138,42 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2015Regenerator, + ES2015TemplateLiterals, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(50u32, 0u32, 0u32)), - (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(37u32, 0u32, 0u32)), - (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(6u32, 0u32, 0u32)), - (Firefox, Version(53u32, 0u32, 0u32)), + (Chrome, Version(41u32, 0u32, 0u32)), + (Safari, Version(13u32, 0u32, 0u32)), + (OperaMobile, Version(28u32, 0u32, 0u32)), + (Samsung, Version(3u32, 4u32, 0u32)), + (Node, Version(4u32, 0u32, 0u32)), + (Firefox, Version(34u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(1u32, 1u32, 0u32)), - (Opera, Version(37u32, 0u32, 0u32)), - (Ios, Version(10u32, 0u32, 0u32)), + (Electron, Version(0u32, 21u32, 0u32)), + (Opera, Version(28u32, 0u32, 0u32)), + (Ios, Version(13u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015NewTarget, - EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(46u32, 0u32, 0u32)), - (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(33u32, 0u32, 0u32)), - (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(5u32, 0u32, 0u32)), - (Firefox, Version(41u32, 0u32, 0u32)), - (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 36u32, 0u32)), - (Opera, Version(33u32, 0u32, 0u32)), - (Ios, Version(10u32, 0u32, 0u32)), - (Edge, Version(14u32, 0u32, 0u32)), - (Es, Version(2015u32, 0, 0)), - ])), - ), - ( - ES2015TypeofSymbol, + ES2015Literals, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(38u32, 0u32, 0u32)), + (Chrome, Version(44u32, 0u32, 0u32)), (Safari, Version(9u32, 0u32, 0u32)), - (OperaMobile, Version(25u32, 0u32, 0u32)), - (Samsung, Version(3u32, 0u32, 0u32)), - (Node, Version(0u32, 12u32, 0u32)), - (Rhino, Version(1u32, 7u32, 13u32)), - (Firefox, Version(36u32, 0u32, 0u32)), + (OperaMobile, Version(32u32, 0u32, 0u32)), + (Samsung, Version(4u32, 0u32, 0u32)), + (Node, Version(4u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 15u32)), + (Firefox, Version(53u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 20u32, 0u32)), - (Opera, Version(25u32, 0u32, 0u32)), + (Electron, Version(0u32, 30u32, 0u32)), + (Opera, Version(31u32, 0u32, 0u32)), (Ios, Version(9u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015BlockScoping, - EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(50u32, 0u32, 0u32)), - (Safari, Version(11u32, 0u32, 0u32)), - (OperaMobile, Version(37u32, 0u32, 0u32)), - (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(6u32, 0u32, 0u32)), - (Firefox, Version(53u32, 0u32, 0u32)), - (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(1u32, 1u32, 0u32)), - (Opera, Version(37u32, 0u32, 0u32)), - (Ios, Version(11u32, 0u32, 0u32)), - (Edge, Version(14u32, 0u32, 0u32)), - (Es, Version(2015u32, 0, 0)), - ])), - ), - ( - ES2015Destructuring, + ES2015FunctionName, EngineTargets::new(FxHashMap::from_iter([ (Chrome, Version(51u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), @@ -219,110 +185,94 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { (Electron, Version(1u32, 2u32, 0u32)), (Opera, Version(38u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), - (Edge, Version(15u32, 0u32, 0u32)), + (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015Spread, + ES2015ArrowFunctions, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(46u32, 0u32, 0u32)), + (Chrome, Version(47u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(33u32, 0u32, 0u32)), + (OperaMobile, Version(34u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(5u32, 0u32, 0u32)), - (Firefox, Version(45u32, 0u32, 0u32)), + (Node, Version(6u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 13u32)), + (Firefox, Version(43u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(0u32, 36u32, 0u32)), - (Opera, Version(33u32, 0u32, 0u32)), + (Opera, Version(34u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015UnicodeRegex, - EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(50u32, 0u32, 0u32)), - (Safari, Version(12u32, 0u32, 0u32)), - (OperaMobile, Version(37u32, 0u32, 0u32)), - (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(6u32, 0u32, 0u32)), - (Firefox, Version(46u32, 0u32, 0u32)), - (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(1u32, 1u32, 0u32)), - (Opera, Version(37u32, 0u32, 0u32)), - (Ios, Version(12u32, 0u32, 0u32)), - (Edge, Version(13u32, 0u32, 0u32)), - (Es, Version(2015u32, 0, 0)), - ])), - ), - ( - ES2015UnicodeEscapes, + ES2015BlockScopedFunctions, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(44u32, 0u32, 0u32)), - (Safari, Version(9u32, 0u32, 0u32)), - (OperaMobile, Version(32u32, 0u32, 0u32)), - (Samsung, Version(4u32, 0u32, 0u32)), + (Chrome, Version(41u32, 0u32, 0u32)), + (Safari, Version(10u32, 0u32, 0u32)), + (OperaMobile, Version(28u32, 0u32, 0u32)), + (Samsung, Version(3u32, 4u32, 0u32)), (Node, Version(4u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 15u32)), - (Firefox, Version(53u32, 0u32, 0u32)), + (Ie, Version(11u32, 0u32, 0u32)), + (Firefox, Version(46u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 30u32, 0u32)), - (Opera, Version(31u32, 0u32, 0u32)), - (Ios, Version(9u32, 0u32, 0u32)), + (Electron, Version(0u32, 21u32, 0u32)), + (Opera, Version(28u32, 0u32, 0u32)), + (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015StickyRegex, + ES2015Classes, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(49u32, 0u32, 0u32)), + (Chrome, Version(46u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(36u32, 0u32, 0u32)), + (OperaMobile, Version(33u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(6u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 15u32)), - (Firefox, Version(3u32, 0u32, 0u32)), + (Node, Version(5u32, 0u32, 0u32)), + (Firefox, Version(45u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 37u32, 0u32)), - (Opera, Version(36u32, 0u32, 0u32)), + (Electron, Version(0u32, 36u32, 0u32)), + (Opera, Version(33u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015ForOf, + ES2015ObjectSuper, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(51u32, 0u32, 0u32)), + (Chrome, Version(46u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(41u32, 0u32, 0u32)), + (OperaMobile, Version(33u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(6u32, 5u32, 0u32)), - (Firefox, Version(53u32, 0u32, 0u32)), + (Node, Version(5u32, 0u32, 0u32)), + (Firefox, Version(45u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(1u32, 2u32, 0u32)), - (Opera, Version(38u32, 0u32, 0u32)), + (Electron, Version(0u32, 36u32, 0u32)), + (Opera, Version(33u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), - (Edge, Version(15u32, 0u32, 0u32)), + (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015ComputedProperties, + ES2015ShorthandProperties, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(44u32, 0u32, 0u32)), - (Safari, Version(7u32, 1u32, 0u32)), - (OperaMobile, Version(32u32, 0u32, 0u32)), + (Chrome, Version(43u32, 0u32, 0u32)), + (Safari, Version(9u32, 0u32, 0u32)), + (OperaMobile, Version(30u32, 0u32, 0u32)), (Samsung, Version(4u32, 0u32, 0u32)), (Node, Version(4u32, 0u32, 0u32)), - (Firefox, Version(34u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 14u32)), + (Firefox, Version(33u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 30u32, 0u32)), - (Opera, Version(31u32, 0u32, 0u32)), - (Ios, Version(8u32, 0u32, 0u32)), + (Electron, Version(0u32, 27u32, 0u32)), + (Opera, Version(30u32, 0u32, 0u32)), + (Ios, Version(9u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), @@ -345,95 +295,111 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2015ShorthandProperties, + ES2015ComputedProperties, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(43u32, 0u32, 0u32)), - (Safari, Version(9u32, 0u32, 0u32)), - (OperaMobile, Version(30u32, 0u32, 0u32)), + (Chrome, Version(44u32, 0u32, 0u32)), + (Safari, Version(7u32, 1u32, 0u32)), + (OperaMobile, Version(32u32, 0u32, 0u32)), (Samsung, Version(4u32, 0u32, 0u32)), (Node, Version(4u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 14u32)), - (Firefox, Version(33u32, 0u32, 0u32)), + (Firefox, Version(34u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 27u32, 0u32)), - (Opera, Version(30u32, 0u32, 0u32)), - (Ios, Version(9u32, 0u32, 0u32)), + (Electron, Version(0u32, 30u32, 0u32)), + (Opera, Version(31u32, 0u32, 0u32)), + (Ios, Version(8u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015ObjectSuper, + ES2015ForOf, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(46u32, 0u32, 0u32)), + (Chrome, Version(51u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(33u32, 0u32, 0u32)), + (OperaMobile, Version(41u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(5u32, 0u32, 0u32)), - (Firefox, Version(45u32, 0u32, 0u32)), + (Node, Version(6u32, 5u32, 0u32)), + (Firefox, Version(53u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 36u32, 0u32)), - (Opera, Version(33u32, 0u32, 0u32)), + (Electron, Version(1u32, 2u32, 0u32)), + (Opera, Version(38u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), - (Edge, Version(13u32, 0u32, 0u32)), + (Edge, Version(15u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015Classes, + ES2015StickyRegex, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(46u32, 0u32, 0u32)), + (Chrome, Version(49u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(33u32, 0u32, 0u32)), + (OperaMobile, Version(36u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), - (Node, Version(5u32, 0u32, 0u32)), - (Firefox, Version(45u32, 0u32, 0u32)), + (Node, Version(6u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 15u32)), + (Firefox, Version(3u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 36u32, 0u32)), - (Opera, Version(33u32, 0u32, 0u32)), + (Electron, Version(0u32, 37u32, 0u32)), + (Opera, Version(36u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015BlockScopedFunctions, + ES2015UnicodeEscapes, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(41u32, 0u32, 0u32)), - (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(28u32, 0u32, 0u32)), - (Samsung, Version(3u32, 4u32, 0u32)), + (Chrome, Version(44u32, 0u32, 0u32)), + (Safari, Version(9u32, 0u32, 0u32)), + (OperaMobile, Version(32u32, 0u32, 0u32)), + (Samsung, Version(4u32, 0u32, 0u32)), (Node, Version(4u32, 0u32, 0u32)), - (Ie, Version(11u32, 0u32, 0u32)), - (Firefox, Version(46u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 15u32)), + (Firefox, Version(53u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 21u32, 0u32)), - (Opera, Version(28u32, 0u32, 0u32)), - (Ios, Version(10u32, 0u32, 0u32)), + (Electron, Version(0u32, 30u32, 0u32)), + (Opera, Version(31u32, 0u32, 0u32)), + (Ios, Version(9u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015ArrowFunctions, + ES2015UnicodeRegex, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(47u32, 0u32, 0u32)), - (Safari, Version(10u32, 0u32, 0u32)), - (OperaMobile, Version(34u32, 0u32, 0u32)), + (Chrome, Version(50u32, 0u32, 0u32)), + (Safari, Version(12u32, 0u32, 0u32)), + (OperaMobile, Version(37u32, 0u32, 0u32)), (Samsung, Version(5u32, 0u32, 0u32)), (Node, Version(6u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 13u32)), - (Firefox, Version(43u32, 0u32, 0u32)), + (Firefox, Version(46u32, 0u32, 0u32)), + (Deno, Version(1u32, 0u32, 0u32)), + (Electron, Version(1u32, 1u32, 0u32)), + (Opera, Version(37u32, 0u32, 0u32)), + (Ios, Version(12u32, 0u32, 0u32)), + (Edge, Version(13u32, 0u32, 0u32)), + (Es, Version(2015u32, 0, 0)), + ])), + ), + ( + ES2015Spread, + EngineTargets::new(FxHashMap::from_iter([ + (Chrome, Version(46u32, 0u32, 0u32)), + (Safari, Version(10u32, 0u32, 0u32)), + (OperaMobile, Version(33u32, 0u32, 0u32)), + (Samsung, Version(5u32, 0u32, 0u32)), + (Node, Version(5u32, 0u32, 0u32)), + (Firefox, Version(45u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(0u32, 36u32, 0u32)), - (Opera, Version(34u32, 0u32, 0u32)), + (Opera, Version(33u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015FunctionName, + ES2015Destructuring, EngineTargets::new(FxHashMap::from_iter([ (Chrome, Version(51u32, 0u32, 0u32)), (Safari, Version(10u32, 0u32, 0u32)), @@ -445,41 +411,75 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { (Electron, Version(1u32, 2u32, 0u32)), (Opera, Version(38u32, 0u32, 0u32)), (Ios, Version(10u32, 0u32, 0u32)), - (Edge, Version(79u32, 0u32, 0u32)), + (Edge, Version(15u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015Literals, + ES2015BlockScoping, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(44u32, 0u32, 0u32)), - (Safari, Version(9u32, 0u32, 0u32)), - (OperaMobile, Version(32u32, 0u32, 0u32)), - (Samsung, Version(4u32, 0u32, 0u32)), - (Node, Version(4u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 15u32)), + (Chrome, Version(50u32, 0u32, 0u32)), + (Safari, Version(11u32, 0u32, 0u32)), + (OperaMobile, Version(37u32, 0u32, 0u32)), + (Samsung, Version(5u32, 0u32, 0u32)), + (Node, Version(6u32, 0u32, 0u32)), (Firefox, Version(53u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 30u32, 0u32)), - (Opera, Version(31u32, 0u32, 0u32)), + (Electron, Version(1u32, 1u32, 0u32)), + (Opera, Version(37u32, 0u32, 0u32)), + (Ios, Version(11u32, 0u32, 0u32)), + (Edge, Version(14u32, 0u32, 0u32)), + (Es, Version(2015u32, 0, 0)), + ])), + ), + ( + ES2015TypeofSymbol, + EngineTargets::new(FxHashMap::from_iter([ + (Chrome, Version(38u32, 0u32, 0u32)), + (Safari, Version(9u32, 0u32, 0u32)), + (OperaMobile, Version(25u32, 0u32, 0u32)), + (Samsung, Version(3u32, 0u32, 0u32)), + (Node, Version(0u32, 12u32, 0u32)), + (Rhino, Version(1u32, 7u32, 13u32)), + (Firefox, Version(36u32, 0u32, 0u32)), + (Deno, Version(1u32, 0u32, 0u32)), + (Electron, Version(0u32, 20u32, 0u32)), + (Opera, Version(25u32, 0u32, 0u32)), (Ios, Version(9u32, 0u32, 0u32)), (Edge, Version(12u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), ), ( - ES2015TemplateLiterals, + ES2015NewTarget, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(41u32, 0u32, 0u32)), - (Safari, Version(13u32, 0u32, 0u32)), - (OperaMobile, Version(28u32, 0u32, 0u32)), - (Samsung, Version(3u32, 4u32, 0u32)), - (Node, Version(4u32, 0u32, 0u32)), - (Firefox, Version(34u32, 0u32, 0u32)), + (Chrome, Version(46u32, 0u32, 0u32)), + (Safari, Version(10u32, 0u32, 0u32)), + (OperaMobile, Version(33u32, 0u32, 0u32)), + (Samsung, Version(5u32, 0u32, 0u32)), + (Node, Version(5u32, 0u32, 0u32)), + (Firefox, Version(41u32, 0u32, 0u32)), + (Deno, Version(1u32, 0u32, 0u32)), + (Electron, Version(0u32, 36u32, 0u32)), + (Opera, Version(33u32, 0u32, 0u32)), + (Ios, Version(10u32, 0u32, 0u32)), + (Edge, Version(14u32, 0u32, 0u32)), + (Es, Version(2015u32, 0, 0)), + ])), + ), + ( + ES2015Regenerator, + EngineTargets::new(FxHashMap::from_iter([ + (Chrome, Version(50u32, 0u32, 0u32)), + (Safari, Version(10u32, 0u32, 0u32)), + (OperaMobile, Version(37u32, 0u32, 0u32)), + (Samsung, Version(5u32, 0u32, 0u32)), + (Node, Version(6u32, 0u32, 0u32)), + (Firefox, Version(53u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(0u32, 21u32, 0u32)), - (Opera, Version(28u32, 0u32, 0u32)), - (Ios, Version(13u32, 0u32, 0u32)), + (Electron, Version(1u32, 1u32, 0u32)), + (Opera, Version(37u32, 0u32, 0u32)), + (Ios, Version(10u32, 0u32, 0u32)), (Edge, Version(13u32, 0u32, 0u32)), (Es, Version(2015u32, 0, 0)), ])), @@ -520,34 +520,34 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2018NamedCapturingGroupsRegex, + ES2018AsyncGeneratorFunctions, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(64u32, 0u32, 0u32)), - (Safari, Version(11u32, 1u32, 0u32)), - (OperaMobile, Version(47u32, 0u32, 0u32)), - (Samsung, Version(9u32, 0u32, 0u32)), + (Chrome, Version(63u32, 0u32, 0u32)), + (Safari, Version(12u32, 0u32, 0u32)), + (OperaMobile, Version(46u32, 0u32, 0u32)), + (Samsung, Version(8u32, 0u32, 0u32)), (Node, Version(10u32, 0u32, 0u32)), - (Firefox, Version(78u32, 0u32, 0u32)), + (Firefox, Version(57u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(3u32, 0u32, 0u32)), - (Opera, Version(51u32, 0u32, 0u32)), - (Ios, Version(11u32, 3u32, 0u32)), + (Opera, Version(50u32, 0u32, 0u32)), + (Ios, Version(12u32, 0u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2018u32, 0, 0)), ])), ), ( - ES2018UnicodePropertyRegex, + ES2018ObjectRestSpread, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(64u32, 0u32, 0u32)), + (Chrome, Version(60u32, 0u32, 0u32)), (Safari, Version(11u32, 1u32, 0u32)), - (OperaMobile, Version(47u32, 0u32, 0u32)), - (Samsung, Version(9u32, 0u32, 0u32)), - (Node, Version(10u32, 0u32, 0u32)), - (Firefox, Version(78u32, 0u32, 0u32)), + (OperaMobile, Version(44u32, 0u32, 0u32)), + (Samsung, Version(8u32, 0u32, 0u32)), + (Node, Version(8u32, 3u32, 0u32)), + (Firefox, Version(55u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(3u32, 0u32, 0u32)), - (Opera, Version(51u32, 0u32, 0u32)), + (Electron, Version(2u32, 0u32, 0u32)), + (Opera, Version(47u32, 0u32, 0u32)), (Ios, Version(11u32, 3u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2018u32, 0, 0)), @@ -572,108 +572,91 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2018LookbehindRegex, + ES2018UnicodePropertyRegex, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(62u32, 0u32, 0u32)), - (Safari, Version(16u32, 4u32, 0u32)), - (OperaMobile, Version(46u32, 0u32, 0u32)), - (Samsung, Version(8u32, 0u32, 0u32)), - (Node, Version(8u32, 10u32, 0u32)), + (Chrome, Version(64u32, 0u32, 0u32)), + (Safari, Version(11u32, 1u32, 0u32)), + (OperaMobile, Version(47u32, 0u32, 0u32)), + (Samsung, Version(9u32, 0u32, 0u32)), + (Node, Version(10u32, 0u32, 0u32)), (Firefox, Version(78u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(3u32, 0u32, 0u32)), - (Opera, Version(49u32, 0u32, 0u32)), - (Ios, Version(16u32, 4u32, 0u32)), + (Opera, Version(51u32, 0u32, 0u32)), + (Ios, Version(11u32, 3u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2018u32, 0, 0)), ])), ), ( - ES2018ObjectRestSpread, + ES2018NamedCapturingGroupsRegex, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(60u32, 0u32, 0u32)), + (Chrome, Version(64u32, 0u32, 0u32)), (Safari, Version(11u32, 1u32, 0u32)), - (OperaMobile, Version(44u32, 0u32, 0u32)), - (Samsung, Version(8u32, 0u32, 0u32)), - (Node, Version(8u32, 3u32, 0u32)), - (Firefox, Version(55u32, 0u32, 0u32)), + (OperaMobile, Version(47u32, 0u32, 0u32)), + (Samsung, Version(9u32, 0u32, 0u32)), + (Node, Version(10u32, 0u32, 0u32)), + (Firefox, Version(78u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), - (Electron, Version(2u32, 0u32, 0u32)), - (Opera, Version(47u32, 0u32, 0u32)), + (Electron, Version(3u32, 0u32, 0u32)), + (Opera, Version(51u32, 0u32, 0u32)), (Ios, Version(11u32, 3u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2018u32, 0, 0)), ])), ), ( - ES2018AsyncGeneratorFunctions, + ES2018LookbehindRegex, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(63u32, 0u32, 0u32)), - (Safari, Version(12u32, 0u32, 0u32)), + (Chrome, Version(62u32, 0u32, 0u32)), + (Safari, Version(16u32, 4u32, 0u32)), (OperaMobile, Version(46u32, 0u32, 0u32)), (Samsung, Version(8u32, 0u32, 0u32)), - (Node, Version(10u32, 0u32, 0u32)), - (Firefox, Version(57u32, 0u32, 0u32)), + (Node, Version(8u32, 10u32, 0u32)), + (Firefox, Version(78u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(3u32, 0u32, 0u32)), - (Opera, Version(50u32, 0u32, 0u32)), - (Ios, Version(12u32, 0u32, 0u32)), + (Opera, Version(49u32, 0u32, 0u32)), + (Ios, Version(16u32, 4u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2018u32, 0, 0)), ])), ), ( - ES2018OptionalCatchBinding, + ES2019JsonStrings, EngineTargets::new(FxHashMap::from_iter([ (Chrome, Version(66u32, 0u32, 0u32)), - (Safari, Version(11u32, 1u32, 0u32)), + (Safari, Version(12u32, 0u32, 0u32)), (OperaMobile, Version(47u32, 0u32, 0u32)), (Samsung, Version(9u32, 0u32, 0u32)), (Node, Version(10u32, 0u32, 0u32)), - (Firefox, Version(58u32, 0u32, 0u32)), + (Rhino, Version(1u32, 7u32, 14u32)), + (Firefox, Version(62u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(3u32, 0u32, 0u32)), (Opera, Version(53u32, 0u32, 0u32)), - (Ios, Version(11u32, 3u32, 0u32)), + (Ios, Version(12u32, 0u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), - (Es, Version(2018u32, 0, 0)), + (Es, Version(2019u32, 0, 0)), ])), ), ( - ES2019JsonStrings, + ES2019OptionalCatchBinding, EngineTargets::new(FxHashMap::from_iter([ (Chrome, Version(66u32, 0u32, 0u32)), - (Safari, Version(12u32, 0u32, 0u32)), + (Safari, Version(11u32, 1u32, 0u32)), (OperaMobile, Version(47u32, 0u32, 0u32)), (Samsung, Version(9u32, 0u32, 0u32)), (Node, Version(10u32, 0u32, 0u32)), - (Rhino, Version(1u32, 7u32, 14u32)), - (Firefox, Version(62u32, 0u32, 0u32)), + (Firefox, Version(58u32, 0u32, 0u32)), (Deno, Version(1u32, 0u32, 0u32)), (Electron, Version(3u32, 0u32, 0u32)), (Opera, Version(53u32, 0u32, 0u32)), - (Ios, Version(12u32, 0u32, 0u32)), + (Ios, Version(11u32, 3u32, 0u32)), (Edge, Version(79u32, 0u32, 0u32)), (Es, Version(2019u32, 0, 0)), ])), ), - ( - ES2019OptionalChaining, - EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(91u32, 0u32, 0u32)), - (Safari, Version(13u32, 1u32, 0u32)), - (OperaMobile, Version(64u32, 0u32, 0u32)), - (Samsung, Version(16u32, 0u32, 0u32)), - (Node, Version(16u32, 9u32, 0u32)), - (Firefox, Version(74u32, 0u32, 0u32)), - (Deno, Version(1u32, 9u32, 0u32)), - (Electron, Version(13u32, 0u32, 0u32)), - (Opera, Version(77u32, 0u32, 0u32)), - (Ios, Version(13u32, 4u32, 0u32)), - (Edge, Version(91u32, 0u32, 0u32)), - (Es, Version(2019u32, 0, 0)), - ])), - ), ( ES2020NullishCoalescingOperator, EngineTargets::new(FxHashMap::from_iter([ @@ -692,19 +675,19 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2020LogicalAssignmentOperators, + ES2020OptionalChaining, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(85u32, 0u32, 0u32)), - (Safari, Version(14u32, 0u32, 0u32)), - (OperaMobile, Version(60u32, 0u32, 0u32)), - (Samsung, Version(14u32, 0u32, 0u32)), - (Node, Version(15u32, 0u32, 0u32)), - (Firefox, Version(79u32, 0u32, 0u32)), - (Deno, Version(1u32, 2u32, 0u32)), - (Electron, Version(10u32, 0u32, 0u32)), - (Opera, Version(71u32, 0u32, 0u32)), - (Ios, Version(14u32, 0u32, 0u32)), - (Edge, Version(85u32, 0u32, 0u32)), + (Chrome, Version(91u32, 0u32, 0u32)), + (Safari, Version(13u32, 1u32, 0u32)), + (OperaMobile, Version(64u32, 0u32, 0u32)), + (Samsung, Version(16u32, 0u32, 0u32)), + (Node, Version(16u32, 9u32, 0u32)), + (Firefox, Version(74u32, 0u32, 0u32)), + (Deno, Version(1u32, 9u32, 0u32)), + (Electron, Version(13u32, 0u32, 0u32)), + (Opera, Version(77u32, 0u32, 0u32)), + (Ios, Version(13u32, 4u32, 0u32)), + (Edge, Version(91u32, 0u32, 0u32)), (Es, Version(2020u32, 0, 0)), ])), ), @@ -745,36 +728,36 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2022PrivateMethods, + ES2021LogicalAssignmentOperators, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(84u32, 0u32, 0u32)), - (Safari, Version(15u32, 0u32, 0u32)), + (Chrome, Version(85u32, 0u32, 0u32)), + (Safari, Version(14u32, 0u32, 0u32)), (OperaMobile, Version(60u32, 0u32, 0u32)), (Samsung, Version(14u32, 0u32, 0u32)), - (Node, Version(14u32, 6u32, 0u32)), - (Firefox, Version(90u32, 0u32, 0u32)), - (Deno, Version(1u32, 0u32, 0u32)), + (Node, Version(15u32, 0u32, 0u32)), + (Firefox, Version(79u32, 0u32, 0u32)), + (Deno, Version(1u32, 2u32, 0u32)), (Electron, Version(10u32, 0u32, 0u32)), - (Opera, Version(70u32, 0u32, 0u32)), - (Ios, Version(15u32, 0u32, 0u32)), - (Edge, Version(84u32, 0u32, 0u32)), - (Es, Version(2022u32, 0, 0)), + (Opera, Version(71u32, 0u32, 0u32)), + (Ios, Version(14u32, 0u32, 0u32)), + (Edge, Version(85u32, 0u32, 0u32)), + (Es, Version(2021u32, 0, 0)), ])), ), ( - ES2022ClassProperties, + ES2022ClassStaticBlock, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(98u32, 0u32, 0u32)), - (Safari, Version(16u32, 0u32, 0u32)), - (OperaMobile, Version(53u32, 0u32, 0u32)), - (Samsung, Version(11u32, 0u32, 0u32)), - (Node, Version(12u32, 0u32, 0u32)), - (Firefox, Version(90u32, 0u32, 0u32)), - (Deno, Version(1u32, 18u32, 0u32)), - (Electron, Version(17u32, 0u32, 0u32)), - (Opera, Version(84u32, 0u32, 0u32)), - (Ios, Version(16u32, 0u32, 0u32)), - (Edge, Version(98u32, 0u32, 0u32)), + (Chrome, Version(94u32, 0u32, 0u32)), + (Safari, Version(16u32, 4u32, 0u32)), + (OperaMobile, Version(66u32, 0u32, 0u32)), + (Samsung, Version(17u32, 0u32, 0u32)), + (Node, Version(16u32, 11u32, 0u32)), + (Firefox, Version(93u32, 0u32, 0u32)), + (Deno, Version(1u32, 14u32, 0u32)), + (Electron, Version(15u32, 0u32, 0u32)), + (Opera, Version(80u32, 0u32, 0u32)), + (Ios, Version(16u32, 4u32, 0u32)), + (Edge, Version(94u32, 0u32, 0u32)), (Es, Version(2022u32, 0, 0)), ])), ), @@ -796,19 +779,36 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { ])), ), ( - ES2022ClassStaticBlock, + ES2022ClassProperties, EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(94u32, 0u32, 0u32)), - (Safari, Version(16u32, 4u32, 0u32)), - (OperaMobile, Version(66u32, 0u32, 0u32)), - (Samsung, Version(17u32, 0u32, 0u32)), - (Node, Version(16u32, 11u32, 0u32)), - (Firefox, Version(93u32, 0u32, 0u32)), - (Deno, Version(1u32, 14u32, 0u32)), - (Electron, Version(15u32, 0u32, 0u32)), - (Opera, Version(80u32, 0u32, 0u32)), - (Ios, Version(16u32, 4u32, 0u32)), - (Edge, Version(94u32, 0u32, 0u32)), + (Chrome, Version(98u32, 0u32, 0u32)), + (Safari, Version(16u32, 0u32, 0u32)), + (OperaMobile, Version(53u32, 0u32, 0u32)), + (Samsung, Version(11u32, 0u32, 0u32)), + (Node, Version(12u32, 0u32, 0u32)), + (Firefox, Version(90u32, 0u32, 0u32)), + (Deno, Version(1u32, 18u32, 0u32)), + (Electron, Version(17u32, 0u32, 0u32)), + (Opera, Version(84u32, 0u32, 0u32)), + (Ios, Version(16u32, 0u32, 0u32)), + (Edge, Version(98u32, 0u32, 0u32)), + (Es, Version(2022u32, 0, 0)), + ])), + ), + ( + ES2022PrivateMethods, + EngineTargets::new(FxHashMap::from_iter([ + (Chrome, Version(84u32, 0u32, 0u32)), + (Safari, Version(15u32, 0u32, 0u32)), + (OperaMobile, Version(60u32, 0u32, 0u32)), + (Samsung, Version(14u32, 0u32, 0u32)), + (Node, Version(14u32, 6u32, 0u32)), + (Firefox, Version(90u32, 0u32, 0u32)), + (Deno, Version(1u32, 0u32, 0u32)), + (Electron, Version(10u32, 0u32, 0u32)), + (Opera, Version(70u32, 0u32, 0u32)), + (Ios, Version(15u32, 0u32, 0u32)), + (Edge, Version(84u32, 0u32, 0u32)), (Es, Version(2022u32, 0, 0)), ])), ), @@ -845,18 +845,6 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { (Es, Version(2024u32, 0, 0)), ])), ), - ( - ES2025RegexpModifiers, - EngineTargets::new(FxHashMap::from_iter([ - (Chrome, Version(125u32, 0u32, 0u32)), - (Edge, Version(125u32, 0u32, 0u32)), - (Electron, Version(31u32, 0u32, 0u32)), - (Opera, Version(111u32, 0u32, 0u32)), - (Node, Version(23u32, 0u32, 0u32)), - (Firefox, Version(132u32, 0u32, 0u32)), - (Es, Version(2025u32, 0, 0)), - ])), - ), ( ES2025DuplicateNamedCapturingGroupsRegex, EngineTargets::new(FxHashMap::from_iter([ @@ -871,6 +859,18 @@ pub fn features() -> &'static FxHashMap<ESFeature, EngineTargets> { (Es, Version(2025u32, 0, 0)), ])), ), + ( + ES2025RegexpModifiers, + EngineTargets::new(FxHashMap::from_iter([ + (Chrome, Version(125u32, 0u32, 0u32)), + (Edge, Version(125u32, 0u32, 0u32)), + (Electron, Version(31u32, 0u32, 0u32)), + (Opera, Version(111u32, 0u32, 0u32)), + (Node, Version(23u32, 0u32, 0u32)), + (Firefox, Version(132u32, 0u32, 0u32)), + (Es, Version(2025u32, 0, 0)), + ])), + ), ]) }) } diff --git a/crates/oxc_transformer/tests/integrations/es_target.rs b/crates/oxc_transformer/tests/integrations/es_target.rs index afc1d2fccb6776..2a486456705ac3 100644 --- a/crates/oxc_transformer/tests/integrations/es_target.rs +++ b/crates/oxc_transformer/tests/integrations/es_target.rs @@ -56,7 +56,7 @@ fn target_list_pass() { let result = TransformOptions::from_target(target).unwrap(); assert!(!result.env.es2019.optional_catch_binding); assert!(!result.env.es2020.nullish_coalescing_operator); - assert!(!result.env.es2021.logical_assignment_operators); + assert!(result.env.es2021.logical_assignment_operators); assert!(result.env.es2022.class_static_block); } diff --git a/tasks/compat_data/data.json b/tasks/compat_data/data.json index c7b05419732741..98e252e96647b8 100644 --- a/tasks/compat_data/data.json +++ b/tasks/compat_data/data.json @@ -1,25 +1,25 @@ [ { - "name": "ReservedWords", + "name": "MemberExpressionLiterals", "es": "ES5", - "babel": "transform-reserved-words", + "babel": "transform-member-expression-literals", "features": [ - "Miscellaneous / Unreserved words" + "Object/array literal extensions / Reserved words as property names" ], "targets": { - "chrome": "13", - "opera": "10.50", + "chrome": "7", + "opera": "12", "edge": "12", "firefox": "2", - "safari": "3.1", - "node": "0.6", + "safari": "5.1", + "node": "0.4", "deno": "1", "ie": "9", - "android": "4.4", + "android": "4", "ios": "6", "samsung": "1", "rhino": "1.7.13", - "opera_mobile": "10.1", + "opera_mobile": "12", "electron": "0.20" } }, @@ -48,26 +48,26 @@ } }, { - "name": "MemberExpressionLiterals", + "name": "ReservedWords", "es": "ES5", - "babel": "transform-member-expression-literals", + "babel": "transform-reserved-words", "features": [ - "Object/array literal extensions / Reserved words as property names" + "Miscellaneous / Unreserved words" ], "targets": { - "chrome": "7", - "opera": "12", + "chrome": "13", + "opera": "10.50", "edge": "12", "firefox": "2", - "safari": "5.1", - "node": "0.4", + "safari": "3.1", + "node": "0.6", "deno": "1", "ie": "9", - "android": "4", + "android": "4.4", "ios": "6", "samsung": "1", "rhino": "1.7.13", - "opera_mobile": "12", + "opera_mobile": "10.1", "electron": "0.20" } }, @@ -97,122 +97,130 @@ } }, { - "name": "Regenerator", - "babel": "transform-regenerator", + "name": "TemplateLiterals", + "babel": "transform-template-literals", "features": [ - "generators" + "template literals" ], "es": "ES2015", "targets": { - "chrome": "50", - "opera": "37", + "chrome": "41", + "opera": "28", "edge": "13", - "firefox": "53", - "safari": "10", - "node": "6", + "firefox": "34", + "safari": "13", + "node": "4", "deno": "1", - "ios": "10", - "samsung": "5", - "opera_mobile": "37", - "electron": "1.1" + "ios": "13", + "samsung": "3.4", + "opera_mobile": "28", + "electron": "0.21" } }, { - "name": "NewTarget", - "babel": "transform-new-target", + "name": "Literals", + "babel": "transform-literals", "features": [ - "new.target", - "arrow functions / lexical \"new.target\" binding" + "Unicode code point escapes" ], "es": "ES2015", "targets": { - "chrome": "46", - "opera": "33", - "edge": "14", - "firefox": "41", - "safari": "10", - "node": "5", + "chrome": "44", + "opera": "31", + "edge": "12", + "firefox": "53", + "safari": "9", + "node": "4", "deno": "1", - "ios": "10", - "samsung": "5", - "opera_mobile": "33", - "electron": "0.36" + "ios": "9", + "samsung": "4", + "rhino": "1.7.15", + "opera_mobile": "32", + "electron": "0.30" } }, { - "name": "TypeofSymbol", - "babel": "transform-typeof-symbol", + "name": "FunctionName", + "babel": "transform-function-name", "features": [ - "Symbol / typeof support" + "function \"name\" property" ], "es": "ES2015", "targets": { - "chrome": "38", - "opera": "25", - "edge": "12", - "firefox": "36", - "safari": "9", - "node": "0.12", + "chrome": "51", + "opera": "38", + "edge": "79", + "firefox": "53", + "safari": "10", + "node": "6.5", "deno": "1", - "ios": "9", - "samsung": "3", - "rhino": "1.7.13", - "opera_mobile": "25", - "electron": "0.20" + "ios": "10", + "samsung": "5", + "opera_mobile": "41", + "electron": "1.2" } }, { - "name": "BlockScoping", - "babel": "transform-block-scoping", + "name": "ArrowFunctions", + "babel": "transform-arrow-functions", "features": [ - "const", - "let", - "generators" + "arrow functions / 0 parameters", + "arrow functions / 1 parameter, no brackets", + "arrow functions / multiple parameters", + "arrow functions / lexical \"this\" binding", + "arrow functions / \"this\" unchanged by call or apply", + "arrow functions / can't be bound, can be curried", + "arrow functions / lexical \"arguments\" binding", + "arrow functions / no line break between params and <code>=></code>", + "arrow functions / correct precedence", + "arrow functions / no \"prototype\" property" ], "es": "ES2015", "targets": { - "chrome": "50", - "opera": "37", - "edge": "14", - "firefox": "53", - "safari": "11", + "chrome": "47", + "opera": "34", + "edge": "13", + "firefox": "43", + "safari": "10", "node": "6", "deno": "1", - "ios": "11", + "ios": "10", "samsung": "5", - "opera_mobile": "37", - "electron": "1.1" + "rhino": "1.7.13", + "opera_mobile": "34", + "electron": "0.36" } }, { - "name": "Destructuring", - "babel": "transform-destructuring", + "name": "BlockScopedFunctions", + "babel": "transform-block-scoped-functions", "features": [ - "destructuring, assignment", - "destructuring, declarations" + "block-level function declaration" ], "es": "ES2015", "targets": { - "chrome": "51", - "opera": "38", - "edge": "15", - "firefox": "53", + "chrome": "41", + "opera": "28", + "edge": "12", + "firefox": "46", "safari": "10", - "node": "6.5", + "node": "4", "deno": "1", + "ie": "11", "ios": "10", - "samsung": "5", - "opera_mobile": "41", - "electron": "1.2" + "samsung": "3.4", + "opera_mobile": "28", + "electron": "0.21" } }, { - "name": "Spread", - "babel": "transform-spread", + "name": "Classes", + "babel": "transform-classes", "features": [ - "spread syntax for iterable objects", "class", - "super" + "super", + "arrow functions / lexical \"super\" binding in constructors", + "arrow functions / lexical \"super\" binding in methods" ], "es": "ES2015", "targets": { @@ -230,93 +238,67 @@ } }, { - "name": "UnicodeRegex", - "babel": "transform-unicode-regex", + "name": "ObjectSuper", + "babel": "transform-object-super", "features": [ - "RegExp \"y\" and \"u\" flags / \"u\" flag, case folding", - "RegExp \"y\" and \"u\" flags / \"u\" flag, Unicode code point escapes", - "RegExp \"y\" and \"u\" flags / \"u\" flag, non-BMP Unicode characters", - "RegExp \"y\" and \"u\" flags / \"u\" flag" + "super" ], "es": "ES2015", "targets": { - "chrome": "50", - "opera": "37", + "chrome": "46", + "opera": "33", "edge": "13", - "firefox": "46", - "safari": "12", - "node": "6", + "firefox": "45", + "safari": "10", + "node": "5", "deno": "1", - "ios": "12", + "ios": "10", "samsung": "5", - "opera_mobile": "37", - "electron": "1.1" + "opera_mobile": "33", + "electron": "0.36" } }, { - "name": "UnicodeEscapes", - "babel": "transform-unicode-escapes", + "name": "ShorthandProperties", + "babel": "transform-shorthand-properties", "features": [ - "Unicode code point escapes" + "object literal extensions / shorthand properties" ], "es": "ES2015", "targets": { - "chrome": "44", - "opera": "31", + "chrome": "43", + "opera": "30", "edge": "12", - "firefox": "53", + "firefox": "33", "safari": "9", "node": "4", "deno": "1", "ios": "9", "samsung": "4", - "rhino": "1.7.15", - "opera_mobile": "32", - "electron": "0.30" + "rhino": "1.7.14", + "opera_mobile": "30", + "electron": "0.27" } }, { - "name": "StickyRegex", - "babel": "transform-sticky-regex", + "name": "DuplicateKeys", + "babel": "transform-duplicate-keys", "features": [ - "RegExp \"y\" and \"u\" flags / \"y\" flag, lastIndex", - "RegExp \"y\" and \"u\" flags / \"y\" flag" + "miscellaneous / duplicate property names in strict mode" ], "es": "ES2015", "targets": { - "chrome": "49", - "opera": "36", - "edge": "13", - "firefox": "3", - "safari": "10", - "node": "6", + "chrome": "42", + "opera": "29", + "edge": "12", + "firefox": "34", + "safari": "9", + "node": "4", "deno": "1", - "ios": "10", - "samsung": "5", - "rhino": "1.7.15", - "opera_mobile": "36", - "electron": "0.37" - } - }, - { - "name": "ForOf", - "babel": "transform-for-of", - "features": [ - "for..of loops" - ], - "es": "ES2015", - "targets": { - "chrome": "51", - "opera": "38", - "edge": "15", - "firefox": "53", - "safari": "10", - "node": "6.5", - "deno": "1", - "ios": "10", - "samsung": "5", - "opera_mobile": "41", - "electron": "1.2" + "ios": "9", + "samsung": "3.4", + "opera_mobile": "29", + "electron": "0.25" } }, { @@ -341,77 +323,102 @@ } }, { - "name": "DuplicateKeys", - "babel": "transform-duplicate-keys", + "name": "ForOf", + "babel": "transform-for-of", "features": [ - "miscellaneous / duplicate property names in strict mode" + "for..of loops" ], "es": "ES2015", "targets": { - "chrome": "42", - "opera": "29", - "edge": "12", - "firefox": "34", - "safari": "9", - "node": "4", + "chrome": "51", + "opera": "38", + "edge": "15", + "firefox": "53", + "safari": "10", + "node": "6.5", "deno": "1", - "ios": "9", - "samsung": "3.4", - "opera_mobile": "29", - "electron": "0.25" + "ios": "10", + "samsung": "5", + "opera_mobile": "41", + "electron": "1.2" } }, { - "name": "ShorthandProperties", - "babel": "transform-shorthand-properties", + "name": "StickyRegex", + "babel": "transform-sticky-regex", "features": [ - "object literal extensions / shorthand properties" + "RegExp \"y\" and \"u\" flags / \"y\" flag, lastIndex", + "RegExp \"y\" and \"u\" flags / \"y\" flag" ], "es": "ES2015", "targets": { - "chrome": "43", - "opera": "30", + "chrome": "49", + "opera": "36", + "edge": "13", + "firefox": "3", + "safari": "10", + "node": "6", + "deno": "1", + "ios": "10", + "samsung": "5", + "rhino": "1.7.15", + "opera_mobile": "36", + "electron": "0.37" + } + }, + { + "name": "UnicodeEscapes", + "babel": "transform-unicode-escapes", + "features": [ + "Unicode code point escapes" + ], + "es": "ES2015", + "targets": { + "chrome": "44", + "opera": "31", "edge": "12", - "firefox": "33", + "firefox": "53", "safari": "9", "node": "4", "deno": "1", "ios": "9", "samsung": "4", - "rhino": "1.7.14", - "opera_mobile": "30", - "electron": "0.27" + "rhino": "1.7.15", + "opera_mobile": "32", + "electron": "0.30" } }, { - "name": "ObjectSuper", - "babel": "transform-object-super", + "name": "UnicodeRegex", + "babel": "transform-unicode-regex", "features": [ - "super" + "RegExp \"y\" and \"u\" flags / \"u\" flag, case folding", + "RegExp \"y\" and \"u\" flags / \"u\" flag, Unicode code point escapes", + "RegExp \"y\" and \"u\" flags / \"u\" flag, non-BMP Unicode characters", + "RegExp \"y\" and \"u\" flags / \"u\" flag" ], "es": "ES2015", "targets": { - "chrome": "46", - "opera": "33", + "chrome": "50", + "opera": "37", "edge": "13", - "firefox": "45", - "safari": "10", - "node": "5", + "firefox": "46", + "safari": "12", + "node": "6", "deno": "1", - "ios": "10", + "ios": "12", "samsung": "5", - "opera_mobile": "33", - "electron": "0.36" + "opera_mobile": "37", + "electron": "1.1" } }, { - "name": "Classes", - "babel": "transform-classes", + "name": "Spread", + "babel": "transform-spread", "features": [ + "spread syntax for iterable objects", "class", - "super", - "arrow functions / lexical \"super\" binding in constructors", - "arrow functions / lexical \"super\" binding in methods" + "super" ], "es": "ES2015", "targets": { @@ -429,120 +436,113 @@ } }, { - "name": "BlockScopedFunctions", - "babel": "transform-block-scoped-functions", + "name": "Destructuring", + "babel": "transform-destructuring", "features": [ - "block-level function declaration" + "destructuring, assignment", + "destructuring, declarations" ], "es": "ES2015", "targets": { - "chrome": "41", - "opera": "28", - "edge": "12", - "firefox": "46", + "chrome": "51", + "opera": "38", + "edge": "15", + "firefox": "53", "safari": "10", - "node": "4", + "node": "6.5", "deno": "1", - "ie": "11", "ios": "10", - "samsung": "3.4", - "opera_mobile": "28", - "electron": "0.21" + "samsung": "5", + "opera_mobile": "41", + "electron": "1.2" } }, { - "name": "ArrowFunctions", - "babel": "transform-arrow-functions", + "name": "BlockScoping", + "babel": "transform-block-scoping", "features": [ - "arrow functions / 0 parameters", - "arrow functions / 1 parameter, no brackets", - "arrow functions / multiple parameters", - "arrow functions / lexical \"this\" binding", - "arrow functions / \"this\" unchanged by call or apply", - "arrow functions / can't be bound, can be curried", - "arrow functions / lexical \"arguments\" binding", - "arrow functions / no line break between params and <code>=></code>", - "arrow functions / correct precedence", - "arrow functions / no \"prototype\" property" + "const", + "let", + "generators" ], "es": "ES2015", "targets": { - "chrome": "47", - "opera": "34", - "edge": "13", - "firefox": "43", - "safari": "10", + "chrome": "50", + "opera": "37", + "edge": "14", + "firefox": "53", + "safari": "11", "node": "6", "deno": "1", - "ios": "10", + "ios": "11", "samsung": "5", - "rhino": "1.7.13", - "opera_mobile": "34", - "electron": "0.36" + "opera_mobile": "37", + "electron": "1.1" } }, { - "name": "FunctionName", - "babel": "transform-function-name", + "name": "TypeofSymbol", + "babel": "transform-typeof-symbol", "features": [ - "function \"name\" property" + "Symbol / typeof support" ], "es": "ES2015", "targets": { - "chrome": "51", - "opera": "38", - "edge": "79", - "firefox": "53", - "safari": "10", - "node": "6.5", + "chrome": "38", + "opera": "25", + "edge": "12", + "firefox": "36", + "safari": "9", + "node": "0.12", "deno": "1", - "ios": "10", - "samsung": "5", - "opera_mobile": "41", - "electron": "1.2" + "ios": "9", + "samsung": "3", + "rhino": "1.7.13", + "opera_mobile": "25", + "electron": "0.20" } }, { - "name": "Literals", - "babel": "transform-literals", + "name": "NewTarget", + "babel": "transform-new-target", "features": [ - "Unicode code point escapes" + "new.target", + "arrow functions / lexical \"new.target\" binding" ], "es": "ES2015", "targets": { - "chrome": "44", - "opera": "31", - "edge": "12", - "firefox": "53", - "safari": "9", - "node": "4", + "chrome": "46", + "opera": "33", + "edge": "14", + "firefox": "41", + "safari": "10", + "node": "5", "deno": "1", - "ios": "9", - "samsung": "4", - "rhino": "1.7.15", - "opera_mobile": "32", - "electron": "0.30" + "ios": "10", + "samsung": "5", + "opera_mobile": "33", + "electron": "0.36" } }, { - "name": "TemplateLiterals", - "babel": "transform-template-literals", + "name": "Regenerator", + "babel": "transform-regenerator", "features": [ - "template literals" + "generators" ], "es": "ES2015", "targets": { - "chrome": "41", - "opera": "28", + "chrome": "50", + "opera": "37", "edge": "13", - "firefox": "34", - "safari": "13", - "node": "4", + "firefox": "53", + "safari": "10", + "node": "6", "deno": "1", - "ios": "13", - "samsung": "3.4", - "opera_mobile": "28", - "electron": "0.21" + "ios": "10", + "samsung": "5", + "opera_mobile": "37", + "electron": "1.1" } }, { @@ -589,45 +589,45 @@ } }, { - "name": "NamedCapturingGroupsRegex", - "babel": "transform-named-capturing-groups-regex", + "name": "AsyncGeneratorFunctions", + "babel": "transform-async-generator-functions", "features": [ - "RegExp named capture groups" + "Asynchronous Iterators" ], "es": "ES2018", "targets": { - "chrome": "64", - "opera": "51", + "chrome": "63", + "opera": "50", "edge": "79", - "firefox": "78", - "safari": "11.1", + "firefox": "57", + "safari": "12", "node": "10", "deno": "1", - "ios": "11.3", - "samsung": "9", - "opera_mobile": "47", + "ios": "12", + "samsung": "8", + "opera_mobile": "46", "electron": "3.0" } }, { - "name": "UnicodePropertyRegex", - "babel": "transform-unicode-property-regex", + "name": "ObjectRestSpread", + "babel": "transform-object-rest-spread", "features": [ - "RegExp Unicode Property Escapes / basic" + "object rest/spread properties" ], "es": "ES2018", "targets": { - "chrome": "64", - "opera": "51", + "chrome": "60", + "opera": "47", "edge": "79", - "firefox": "78", + "firefox": "55", "safari": "11.1", - "node": "10", + "node": "8.3", "deno": "1", "ios": "11.3", - "samsung": "9", - "opera_mobile": "47", - "electron": "3.0" + "samsung": "8", + "opera_mobile": "44", + "electron": "2.0" } }, { @@ -641,92 +641,50 @@ "chrome": "62", "opera": "49", "edge": "79", - "firefox": "78", - "safari": "11.1", - "node": "8.10", - "deno": "1", - "ios": "11.3", - "samsung": "8", - "rhino": "1.7.15", - "opera_mobile": "46", - "electron": "3.0" - } - }, - { - "name": "LookbehindRegex", - "babel": null, - "features": [ - "RegExp Lookbehind Assertions" - ], - "es": "ES2018", - "targets": { - "chrome": "62", - "opera": "49", - "edge": "79", - "firefox": "78", - "safari": "16.4", - "node": "8.10", - "deno": "1", - "ios": "16.4", - "samsung": "8", - "opera_mobile": "46", - "electron": "3.0" - } - }, - { - "name": "ObjectRestSpread", - "babel": "transform-object-rest-spread", - "features": [ - "object rest/spread properties" - ], - "es": "ES2018", - "targets": { - "chrome": "60", - "opera": "47", - "edge": "79", - "firefox": "55", + "firefox": "78", "safari": "11.1", - "node": "8.3", + "node": "8.10", "deno": "1", "ios": "11.3", "samsung": "8", - "opera_mobile": "44", - "electron": "2.0" + "rhino": "1.7.15", + "opera_mobile": "46", + "electron": "3.0" } }, { - "name": "AsyncGeneratorFunctions", - "babel": "transform-async-generator-functions", + "name": "UnicodePropertyRegex", + "babel": "transform-unicode-property-regex", "features": [ - "Asynchronous Iterators" + "RegExp Unicode Property Escapes / basic" ], "es": "ES2018", "targets": { - "chrome": "63", - "opera": "50", + "chrome": "64", + "opera": "51", "edge": "79", - "firefox": "57", - "safari": "12", + "firefox": "78", + "safari": "11.1", "node": "10", "deno": "1", - "ios": "12", - "samsung": "8", - "opera_mobile": "46", + "ios": "11.3", + "samsung": "9", + "opera_mobile": "47", "electron": "3.0" } }, { - "name": "OptionalCatchBinding", - "babel": "transform-optional-catch-binding", + "name": "NamedCapturingGroupsRegex", + "babel": "transform-named-capturing-groups-regex", "features": [ - "optional catch binding" + "RegExp named capture groups" ], "es": "ES2018", "targets": { - "chrome": "66", - "opera": "53", + "chrome": "64", + "opera": "51", "edge": "79", - "firefox": "58", + "firefox": "78", "safari": "11.1", "node": "10", "deno": "1", @@ -736,6 +694,27 @@ "electron": "3.0" } }, + { + "name": "LookbehindRegex", + "babel": null, + "features": [ + "RegExp Lookbehind Assertions" + ], + "es": "ES2018", + "targets": { + "chrome": "62", + "opera": "49", + "edge": "79", + "firefox": "78", + "safari": "16.4", + "node": "8.10", + "deno": "1", + "ios": "16.4", + "samsung": "8", + "opera_mobile": "46", + "electron": "3.0" + } + }, { "name": "JsonStrings", "babel": "transform-json-strings", @@ -759,24 +738,24 @@ } }, { - "name": "OptionalChaining", - "babel": "transform-optional-chaining", + "name": "OptionalCatchBinding", + "babel": "transform-optional-catch-binding", "features": [ - "optional chaining operator (?.)" + "optional catch binding" ], "es": "ES2019", "targets": { - "chrome": "91", - "opera": "77", - "edge": "91", - "firefox": "74", - "safari": "13.1", - "node": "16.9", - "deno": "1.9", - "ios": "13.4", - "samsung": "16", - "opera_mobile": "64", - "electron": "13.0" + "chrome": "66", + "opera": "53", + "edge": "79", + "firefox": "58", + "safari": "11.1", + "node": "10", + "deno": "1", + "ios": "11.3", + "samsung": "9", + "opera_mobile": "47", + "electron": "3.0" } }, { @@ -801,24 +780,24 @@ } }, { - "name": "LogicalAssignmentOperators", - "babel": "transform-logical-assignment-operators", + "name": "OptionalChaining", + "babel": "transform-optional-chaining", "features": [ - "Logical Assignment" + "optional chaining operator (?.)" ], "es": "ES2020", "targets": { - "chrome": "85", - "opera": "71", - "edge": "85", - "firefox": "79", - "safari": "14", - "node": "15", - "deno": "1.2", - "ios": "14", - "samsung": "14", - "opera_mobile": "60", - "electron": "10.0" + "chrome": "91", + "opera": "77", + "edge": "91", + "firefox": "74", + "safari": "13.1", + "node": "16.9", + "deno": "1.9", + "ios": "13.4", + "samsung": "16", + "opera_mobile": "64", + "electron": "13.0" } }, { @@ -866,24 +845,66 @@ } }, { - "name": "PrivateMethods", - "babel": "transform-private-methods", + "name": "LogicalAssignmentOperators", + "babel": "transform-logical-assignment-operators", "features": [ - "private class methods" + "Logical Assignment" + ], + "es": "ES2021", + "targets": { + "chrome": "85", + "opera": "71", + "edge": "85", + "firefox": "79", + "safari": "14", + "node": "15", + "deno": "1.2", + "ios": "14", + "samsung": "14", + "opera_mobile": "60", + "electron": "10.0" + } + }, + { + "name": "ClassStaticBlock", + "babel": "transform-class-static-block", + "features": [ + "Class static initialization blocks" ], "es": "ES2022", "targets": { - "chrome": "84", - "opera": "70", - "edge": "84", + "chrome": "94", + "opera": "80", + "edge": "94", + "firefox": "93", + "safari": "16.4", + "node": "16.11", + "deno": "1.14", + "ios": "16.4", + "samsung": "17", + "opera_mobile": "66", + "electron": "15.0" + } + }, + { + "name": "PrivatePropertyInObject", + "babel": "transform-private-property-in-object", + "features": [ + "Ergonomic brand checks for private fields" + ], + "es": "ES2022", + "targets": { + "chrome": "91", + "opera": "77", + "edge": "91", "firefox": "90", "safari": "15", - "node": "14.6", - "deno": "1", + "node": "16.9", + "deno": "1.9", "ios": "15", - "samsung": "14", - "opera_mobile": "60", - "electron": "10.0" + "samsung": "16", + "opera_mobile": "64", + "electron": "13.0" } }, { @@ -912,45 +933,24 @@ } }, { - "name": "PrivatePropertyInObject", - "babel": "transform-private-property-in-object", + "name": "PrivateMethods", + "babel": "transform-private-methods", "features": [ - "Ergonomic brand checks for private fields" + "private class methods" ], "es": "ES2022", "targets": { - "chrome": "91", - "opera": "77", - "edge": "91", + "chrome": "84", + "opera": "70", + "edge": "84", "firefox": "90", "safari": "15", - "node": "16.9", - "deno": "1.9", + "node": "14.6", + "deno": "1", "ios": "15", - "samsung": "16", - "opera_mobile": "64", - "electron": "13.0" - } - }, - { - "name": "ClassStaticBlock", - "babel": "transform-class-static-block", - "features": [ - "Class static initialization blocks" - ], - "es": "ES2022", - "targets": { - "chrome": "94", - "opera": "80", - "edge": "94", - "firefox": "93", - "safari": "16.4", - "node": "16.11", - "deno": "1.14", - "ios": "16.4", - "samsung": "17", - "opera_mobile": "66", - "electron": "15.0" + "samsung": "14", + "opera_mobile": "60", + "electron": "10.0" } }, { @@ -997,22 +997,6 @@ "electron": "24.0" } }, - { - "name": "RegexpModifiers", - "babel": "transform-regexp-modifiers", - "features": [ - "RegExp Pattern Modifiers" - ], - "es": "ES2025", - "targets": { - "chrome": "125", - "opera": "111", - "edge": "125", - "firefox": "132", - "node": "23", - "electron": "31.0" - } - }, { "name": "DuplicateNamedCapturingGroupsRegex", "babel": "transform-duplicate-named-capturing-groups-regex", @@ -1030,5 +1014,21 @@ "ios": "17.4", "electron": "31.0" } + }, + { + "name": "RegexpModifiers", + "babel": "transform-regexp-modifiers", + "features": [ + "RegExp Pattern Modifiers" + ], + "es": "ES2025", + "targets": { + "chrome": "125", + "opera": "111", + "edge": "125", + "firefox": "132", + "node": "23", + "electron": "31.0" + } } ] diff --git a/tasks/compat_data/es-features.js b/tasks/compat_data/es-features.js index 856ba4033e6d79..7e5414a62a271e 100644 --- a/tasks/compat_data/es-features.js +++ b/tasks/compat_data/es-features.js @@ -8,10 +8,12 @@ const f = (es) => (item) => { const es5 = [ { - name: 'ReservedWords', + name: 'MemberExpressionLiterals', es: 'ES5', - babel: 'transform-reserved-words', - features: ['Miscellaneous / Unreserved words'], + babel: 'transform-member-expression-literals', + features: [ + 'Object/array literal extensions / Reserved words as property names', + ], }, { name: 'PropertyLiterals', @@ -22,12 +24,10 @@ const es5 = [ ], }, { - name: 'MemberExpressionLiterals', + name: 'ReservedWords', es: 'ES5', - babel: 'transform-member-expression-literals', - features: [ - 'Object/array literal extensions / Reserved words as property names', - ], + babel: 'transform-reserved-words', + features: ['Miscellaneous / Unreserved words'], }, ].map(f('ES5')); @@ -44,67 +44,60 @@ const es2015 = [ ], }, { - name: 'Regenerator', - babel: 'transform-regenerator', - features: ['generators'], - }, - { - name: 'NewTarget', - babel: 'transform-new-target', - features: ['new.target', 'arrow functions / lexical "new.target" binding'], - }, - { - name: 'TypeofSymbol', - babel: 'transform-typeof-symbol', - features: ['Symbol / typeof support'], - }, - { - name: 'BlockScoping', - babel: 'transform-block-scoping', - features: ['const', 'let', 'generators'], + name: 'TemplateLiterals', + babel: 'transform-template-literals', + features: ['template literals'], }, { - name: 'Destructuring', - babel: 'transform-destructuring', - features: ['destructuring, assignment', 'destructuring, declarations'], + name: 'Literals', + babel: 'transform-literals', + features: ['Unicode code point escapes'], }, { - name: 'Spread', - babel: 'transform-spread', - features: ['spread syntax for iterable objects', 'class', 'super'], + name: 'FunctionName', + babel: 'transform-function-name', + features: ['function "name" property'], }, { - name: 'UnicodeRegex', - babel: 'transform-unicode-regex', + name: 'ArrowFunctions', + babel: 'transform-arrow-functions', features: [ - 'RegExp "y" and "u" flags / "u" flag, case folding', - 'RegExp "y" and "u" flags / "u" flag, Unicode code point escapes', - 'RegExp "y" and "u" flags / "u" flag, non-BMP Unicode characters', - 'RegExp "y" and "u" flags / "u" flag', + 'arrow functions / 0 parameters', + 'arrow functions / 1 parameter, no brackets', + 'arrow functions / multiple parameters', + 'arrow functions / lexical "this" binding', + 'arrow functions / "this" unchanged by call or apply', + "arrow functions / can't be bound, can be curried", + 'arrow functions / lexical "arguments" binding', + 'arrow functions / no line break between params and <code>=></code>', + 'arrow functions / correct precedence', + 'arrow functions / no "prototype" property', ], }, { - name: 'UnicodeEscapes', - babel: 'transform-unicode-escapes', - features: ['Unicode code point escapes'], + name: 'BlockScopedFunctions', + babel: 'transform-block-scoped-functions', + features: ['block-level function declaration'], }, { - name: 'StickyRegex', - babel: 'transform-sticky-regex', + name: 'Classes', + babel: 'transform-classes', features: [ - 'RegExp "y" and "u" flags / "y" flag, lastIndex', - 'RegExp "y" and "u" flags / "y" flag', + 'class', + 'super', + 'arrow functions / lexical "super" binding in constructors', + 'arrow functions / lexical "super" binding in methods', ], }, { - name: 'ForOf', - babel: 'transform-for-of', - features: ['for..of loops'], + name: 'ObjectSuper', + babel: 'transform-object-super', + features: ['super'], }, { - name: 'ComputedProperties', - babel: 'transform-computed-properties', - features: ['object literal extensions / computed properties'], + name: 'ShorthandProperties', + babel: 'transform-shorthand-properties', + features: ['object literal extensions / shorthand properties'], }, { name: 'DuplicateKeys', @@ -112,60 +105,67 @@ const es2015 = [ features: ['miscellaneous / duplicate property names in strict mode'], }, { - name: 'ShorthandProperties', - babel: 'transform-shorthand-properties', - features: ['object literal extensions / shorthand properties'], + name: 'ComputedProperties', + babel: 'transform-computed-properties', + features: ['object literal extensions / computed properties'], }, { - name: 'ObjectSuper', - babel: 'transform-object-super', - features: ['super'], + name: 'ForOf', + babel: 'transform-for-of', + features: ['for..of loops'], }, { - name: 'Classes', - babel: 'transform-classes', + name: 'StickyRegex', + babel: 'transform-sticky-regex', features: [ - 'class', - 'super', - 'arrow functions / lexical "super" binding in constructors', - 'arrow functions / lexical "super" binding in methods', + 'RegExp "y" and "u" flags / "y" flag, lastIndex', + 'RegExp "y" and "u" flags / "y" flag', ], }, { - name: 'BlockScopedFunctions', - babel: 'transform-block-scoped-functions', - features: ['block-level function declaration'], + name: 'UnicodeEscapes', + babel: 'transform-unicode-escapes', + features: ['Unicode code point escapes'], }, { - name: 'ArrowFunctions', - babel: 'transform-arrow-functions', + name: 'UnicodeRegex', + babel: 'transform-unicode-regex', features: [ - 'arrow functions / 0 parameters', - 'arrow functions / 1 parameter, no brackets', - 'arrow functions / multiple parameters', - 'arrow functions / lexical "this" binding', - 'arrow functions / "this" unchanged by call or apply', - "arrow functions / can't be bound, can be curried", - 'arrow functions / lexical "arguments" binding', - 'arrow functions / no line break between params and <code>=></code>', - 'arrow functions / correct precedence', - 'arrow functions / no "prototype" property', + 'RegExp "y" and "u" flags / "u" flag, case folding', + 'RegExp "y" and "u" flags / "u" flag, Unicode code point escapes', + 'RegExp "y" and "u" flags / "u" flag, non-BMP Unicode characters', + 'RegExp "y" and "u" flags / "u" flag', ], }, { - name: 'FunctionName', - babel: 'transform-function-name', - features: ['function "name" property'], + name: 'Spread', + babel: 'transform-spread', + features: ['spread syntax for iterable objects', 'class', 'super'], }, { - name: 'Literals', - babel: 'transform-literals', - features: ['Unicode code point escapes'], + name: 'Destructuring', + babel: 'transform-destructuring', + features: ['destructuring, assignment', 'destructuring, declarations'], }, { - name: 'TemplateLiterals', - babel: 'transform-template-literals', - features: ['template literals'], + name: 'BlockScoping', + babel: 'transform-block-scoping', + features: ['const', 'let', 'generators'], + }, + { + name: 'TypeofSymbol', + babel: 'transform-typeof-symbol', + features: ['Symbol / typeof support'], + }, + { + name: 'NewTarget', + babel: 'transform-new-target', + features: ['new.target', 'arrow functions / lexical "new.target" binding'], + }, + { + name: 'Regenerator', + babel: 'transform-regenerator', + features: ['generators'], }, ].map(f('ES2015')); @@ -187,14 +187,14 @@ const es2017 = [ const es2018 = [ { - name: 'NamedCapturingGroupsRegex', - babel: 'transform-named-capturing-groups-regex', - features: ['RegExp named capture groups'], + name: 'AsyncGeneratorFunctions', + babel: 'transform-async-generator-functions', + features: ['Asynchronous Iterators'], }, { - name: 'UnicodePropertyRegex', - babel: 'transform-unicode-property-regex', - features: ['RegExp Unicode Property Escapes / basic'], + name: 'ObjectRestSpread', + babel: 'transform-object-rest-spread', + features: ['object rest/spread properties'], }, { name: 'DotallRegex', @@ -202,24 +202,19 @@ const es2018 = [ features: ['s (dotAll) flag for regular expressions'], }, { - name: 'LookbehindRegex', - babel: null, - features: ['RegExp Lookbehind Assertions'], - }, - { - name: 'ObjectRestSpread', - babel: 'transform-object-rest-spread', - features: ['object rest/spread properties'], + name: 'UnicodePropertyRegex', + babel: 'transform-unicode-property-regex', + features: ['RegExp Unicode Property Escapes / basic'], }, { - name: 'AsyncGeneratorFunctions', - babel: 'transform-async-generator-functions', - features: ['Asynchronous Iterators'], + name: 'NamedCapturingGroupsRegex', + babel: 'transform-named-capturing-groups-regex', + features: ['RegExp named capture groups'], }, { - name: 'OptionalCatchBinding', - babel: 'transform-optional-catch-binding', - features: ['optional catch binding'], + name: 'LookbehindRegex', + babel: null, + features: ['RegExp Lookbehind Assertions'], }, ].map(f('ES2018')); @@ -230,9 +225,9 @@ const es2019 = [ features: ['JSON superset'], }, { - name: 'OptionalChaining', - babel: 'transform-optional-chaining', - features: ['optional chaining operator (?.)'], + name: 'OptionalCatchBinding', + babel: 'transform-optional-catch-binding', + features: ['optional catch binding'], }, ].map(f('ES2019')); @@ -243,9 +238,9 @@ const es2020 = [ features: ['nullish coalescing operator (??)'], }, { - name: 'LogicalAssignmentOperators', - babel: 'transform-logical-assignment-operators', - features: ['Logical Assignment'], + name: 'OptionalChaining', + babel: 'transform-optional-chaining', + features: ['optional chaining operator (?.)'], }, { name: 'BigInt', @@ -260,13 +255,23 @@ const es2021 = [ babel: 'transform-numeric-separator', features: ['numeric separators'], }, + { + name: 'LogicalAssignmentOperators', + babel: 'transform-logical-assignment-operators', + features: ['Logical Assignment'], + }, ].map(f('ES2021')); const es2022 = [ { - name: 'PrivateMethods', - babel: 'transform-private-methods', - features: ['private class methods'], + name: 'ClassStaticBlock', + babel: 'transform-class-static-block', + features: ['Class static initialization blocks'], + }, + { + name: 'PrivatePropertyInObject', + babel: 'transform-private-property-in-object', + features: ['Ergonomic brand checks for private fields'], }, { name: 'ClassProperties', @@ -280,14 +285,9 @@ const es2022 = [ ], }, { - name: 'PrivatePropertyInObject', - babel: 'transform-private-property-in-object', - features: ['Ergonomic brand checks for private fields'], - }, - { - name: 'ClassStaticBlock', - babel: 'transform-class-static-block', - features: ['Class static initialization blocks'], + name: 'PrivateMethods', + babel: 'transform-private-methods', + features: ['private class methods'], }, { name: 'MatchIndicesRegex', @@ -313,16 +313,16 @@ const es2024 = [ ].map(f('ES2024')); const es2025 = [ - { - name: 'RegexpModifiers', - babel: 'transform-regexp-modifiers', - features: ['RegExp Pattern Modifiers'], - }, { name: 'DuplicateNamedCapturingGroupsRegex', babel: 'transform-duplicate-named-capturing-groups-regex', features: ['Duplicate named capturing groups'], }, + { + name: 'RegexpModifiers', + babel: 'transform-regexp-modifiers', + features: ['RegExp Pattern Modifiers'], + }, ].map(f('ES2025')); module.exports = [ From f0affa20c62d21d927b0a80961f9519d55f626e1 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:28:14 +0000 Subject: [PATCH 07/27] docs(ast): improve docs examples for `PropertyDefinition` (#7287) --- crates/oxc_ast/src/ast/js.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index fd207cf18a4508..06107e41dd75eb 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1928,13 +1928,14 @@ pub struct PropertyDefinition<'a> { /// Initialized value in the declaration. /// /// ## Example - /// ``` + /// ```ts /// class Foo { - /// x = 5 // Some(NumericLiteral) - /// y: string // None + /// x = 5; // Some(NumericLiteral) + /// y; // None + /// z: string; // None /// /// constructor() { - /// this.y = "hello" + /// this.z = "hello"; /// } /// } /// ``` @@ -1942,10 +1943,10 @@ pub struct PropertyDefinition<'a> { /// Property was declared with a computed key /// /// ## Example - /// ```ts + /// ```js /// class Foo { - /// ["a"]: string // true - /// b: number // false + /// ["a"]: 1; // true + /// b: 2; // false /// } /// ``` pub computed: bool, @@ -1956,12 +1957,12 @@ pub struct PropertyDefinition<'a> { /// ## Example /// ```ts /// class Foo { - /// x: number // false - /// declare y: string // true + /// x: number; // false + /// declare y: string; // true /// } /// /// declare class Bar { - /// x: number // false + /// x: number; // false /// } /// ``` #[ts] @@ -1989,10 +1990,10 @@ pub struct PropertyDefinition<'a> { /// /// ```ts /// class Foo { - /// public w: number // Some(TSAccessibility::Public) - /// private x: string // Some(TSAccessibility::Private) - /// protected y: boolean // Some(TSAccessibility::Protected) - /// readonly z // None + /// public w: number; // Some(TSAccessibility::Public) + /// private x: string; // Some(TSAccessibility::Private) + /// protected y: boolean; // Some(TSAccessibility::Protected) + /// readonly z; // None /// } /// ``` #[ts] From f0dee76a4d4c9296bd4d2308f0d6d923d5ba8805 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:58:16 +0000 Subject: [PATCH 08/27] style(ast_tools): fix wonky formatting (#7288) Follow-on after #7283. Pure refactor. `rustfmt` was malfunctioning on this code for some reason. Alter the code slightly so it formats it nicely. --- tasks/ast_tools/src/generators/typescript.rs | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tasks/ast_tools/src/generators/typescript.rs b/tasks/ast_tools/src/generators/typescript.rs index bcad09ef3f690e..ff4c67afd2173e 100644 --- a/tasks/ast_tools/src/generators/typescript.rs +++ b/tasks/ast_tools/src/generators/typescript.rs @@ -108,19 +108,20 @@ fn typescript_struct(def: &StructDef, always_flatten_structs: &FxHashSet<TypeId> let ident = field.ident().unwrap(); if let Some(append_after) = append_to.get(&ident.to_string()) { - let after_type = - if let Some(ty) = &append_after.markers.derive_attributes.estree.typescript_type { - ty.clone() + let ts_type = &append_after.markers.derive_attributes.estree.typescript_type; + let after_type = if let Some(ty) = ts_type { + ty.clone() + } else { + let typ = append_after.typ.name(); + if let TypeName::Opt(inner) = typ { + type_to_string(inner) } else { - let typ = append_after.typ.name(); - if let TypeName::Opt(inner) = typ { - type_to_string(inner) - } else { - panic!( + panic!( "expected field labeled with append_to to be Option<...>, but found {typ}" ); - } - }; + } + }; + if let Some(inner) = ty.strip_prefix("Array<") { ty = format!("Array<{after_type} | {inner}"); } else { From 8da23692fc9aa1afbed50d825c0e7a30944be9da Mon Sep 17 00:00:00 2001 From: Song Gao <158983297@qq.com> Date: Fri, 15 Nov 2024 07:04:53 +0800 Subject: [PATCH 09/27] build(traverse): generate files in parallel (#7281) Create type files in parallel. Although it's already pretty fast, always better to be faster. --- crates/oxc_traverse/scripts/build.mjs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/oxc_traverse/scripts/build.mjs b/crates/oxc_traverse/scripts/build.mjs index 4f57fa8f2199b1..584d8097bcfe05 100644 --- a/crates/oxc_traverse/scripts/build.mjs +++ b/crates/oxc_traverse/scripts/build.mjs @@ -30,10 +30,13 @@ const PREAMBLE = '// Auto-generated code, DO NOT EDIT DIRECTLY!\n' + const types = await getTypesFromCode(); const outputDirPath = pathJoin(fileURLToPath(import.meta.url), '../../src/generated'); -await writeToFile('traverse.rs', generateTraverseTraitCode(types)); -await writeToFile('ancestor.rs', generateAncestorsCode(types)); -await writeToFile('walk.rs', generateWalkFunctionsCode(types)); -await writeToFile('scopes_collector.rs', generateScopesCollectorCode(types)); + +await Promise.all([ + writeToFile('traverse.rs', generateTraverseTraitCode(types)), + writeToFile('ancestor.rs', generateAncestorsCode(types)), + writeToFile('walk.rs', generateWalkFunctionsCode(types)), + writeToFile('scopes_collector.rs', generateScopesCollectorCode(types)), +]); /** * @param {string} filename From 33ec4e6182f4e53c270085df45b1612bd419e33e Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Fri, 15 Nov 2024 02:56:49 +0000 Subject: [PATCH 10/27] fix(codegen): fix arithmetic overflow printing unspanned `NewExpression` (#7289) `self.span.end - 1` overflows if the `NewExpression` is generated in transformer and has no span, so `self.span.end == 0`. --- crates/oxc_codegen/src/gen.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 41c95d908fd593..3568417077daf9 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2067,7 +2067,7 @@ impl<'a> GenExpr for NewExpression<'a> { p.print_str("new "); self.callee.print_expr(p, Precedence::New, Context::FORBID_CALL); p.print_ascii_byte(b'('); - let has_comment = p.has_comment(self.span.end - 1) + let has_comment = (!self.span.is_unspanned() && p.has_comment(self.span.end - 1)) || self.arguments.iter().any(|item| p.has_comment(item.span().start)); if has_comment { p.indent(); From 8d8f34cfb5b1898959456b86eda9c1703bf31d99 Mon Sep 17 00:00:00 2001 From: Boshen <boshenc@gmail.com> Date: Fri, 15 Nov 2024 12:48:56 +0800 Subject: [PATCH 11/27] chore(tasks/coverage): update runtime.snap --- tasks/coverage/snapshots/runtime.snap | 766 +++++++++++++++++++++++++- 1 file changed, 764 insertions(+), 2 deletions(-) diff --git a/tasks/coverage/snapshots/runtime.snap b/tasks/coverage/snapshots/runtime.snap index ef6f9e9948ae30..51f7b2b1b3491c 100644 --- a/tasks/coverage/snapshots/runtime.snap +++ b/tasks/coverage/snapshots/runtime.snap @@ -2,10 +2,451 @@ commit: 06454619 runtime Summary: AST Parsed : 18055/18055 (100.00%) -Positive Passed: 18046/18055 (99.95%) +Positive Passed: 17796/18055 (98.57%) +tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-static-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-static-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-static-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-static-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-gen-meth-static-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-static-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-static-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-static-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-static-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-static-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-static-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-static-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-static-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-static-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-gen-meth-static-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-static-args-trailing-comma-multiple.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-static-args-trailing-comma-null.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-static-args-trailing-comma-single-args.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-static-args-trailing-comma-spread-operator.js +transform error: Test262Error: Expected SameValue(«0», «4») to be true + +tasks/coverage/test262/test/language/arguments-object/cls-expr-async-private-gen-meth-static-args-trailing-comma-undefined.js +transform error: Test262Error: Expected SameValue(«0», «2») to be true + tasks/coverage/test262/test/language/expressions/assignment/fn-name-lhs-cover.js codegen error: Test262Error: descriptor value should be ; object value should be +tasks/coverage/test262/test/language/expressions/async-arrow-function/forbidden-ext/b1/async-arrow-function-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-arrow-function/forbidden-ext/b1/async-arrow-function-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-arrow-function/prototype.js +transform error: Test262Error: Expected SameValue(«function () { [native code] }», «[object AsyncFunction]») to be true + +tasks/coverage/test262/test/language/expressions/async-function/forbidden-ext/b1/async-func-expr-named-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-function/forbidden-ext/b1/async-func-expr-named-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-function/forbidden-ext/b1/async-func-expr-nameless-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-function/forbidden-ext/b1/async-func-expr-nameless-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-reassign-fn-name-in-body-in-arrow.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-reassign-fn-name-in-body-in-eval.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-reassign-fn-name-in-body.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body-in-arrow.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body-in-eval.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-function/named-strict-error-reassign-fn-name-in-body.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/default-proto.js +transform error: Test262Error: fn.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/forbidden-ext/b1/async-gen-func-expr-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/forbidden-ext/b1/async-gen-func-expr-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/forbidden-ext/b1/async-gen-named-func-expr-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/forbidden-ext/b1/async-gen-named-func-expr-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body-in-arrow.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body-in-eval.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-no-strict-reassign-fn-name-in-body.js +transform error: Test262Error: Expected SameValue(«1», «function BindingIdentifier() { + return _BindingIdentifier.apply(this, arguments); + }») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body-in-arrow.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body-in-eval.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-strict-error-reassign-fn-name-in-body.js +transform error: Test262Error: Expected SameValue(«0», «1») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/named-yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/async-generator/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/await/await-monkey-patched-promise.js +transform error: Test262Error: Monkey-patched "then" on native promises should not be called. Expected SameValue(«1», «0») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/async-gen-method-static/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/class/async-method/dflt-params-abrupt.js +transform error: Test262Error: + +tasks/coverage/test262/test/language/expressions/class/async-method/dflt-params-ref-later.js +transform error: ReferenceError: Cannot access 'y' before initialization + +tasks/coverage/test262/test/language/expressions/class/async-method/dflt-params-ref-self.js +transform error: ReferenceError: Cannot access 'x' before initialization + +tasks/coverage/test262/test/language/expressions/class/async-method/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/class/async-method-static/dflt-params-abrupt.js +transform error: Test262Error: + +tasks/coverage/test262/test/language/expressions/class/async-method-static/dflt-params-ref-later.js +transform error: ReferenceError: Cannot access 'y' before initialization + +tasks/coverage/test262/test/language/expressions/class/async-method-static/dflt-params-ref-self.js +transform error: ReferenceError: Cannot access 'x' before initialization + +tasks/coverage/test262/test/language/expressions/class/async-method-static/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-gen-private-method-static/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/class/elements/async-private-method/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/class/elements/async-private-method-static/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/class/heritage-arrow-function.js +transform error: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all + +tasks/coverage/test262/test/language/expressions/class/heritage-async-arrow-function.js +transform error: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all + tasks/coverage/test262/test/language/expressions/does-not-equals/bigint-and-object.js minify error: Test262Error: The result of (0n != {valueOf: function() {return 0n;}}) is false Expected SameValue(«true», «false») to be true @@ -18,11 +459,332 @@ transform error: Test262Error: (-1n) ** -1n throws RangeError Expected a RangeEr tasks/coverage/test262/test/language/expressions/object/__proto__-permitted-dup-shorthand.js codegen error: Test262Error: Expected SameValue(«[object Object]», «2») to be true +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-gen-yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-abrupt.js +transform error: Test262Error: + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-ref-later.js +transform error: ReferenceError: Cannot access 'y' before initialization + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-dflt-params-ref-self.js +transform error: ReferenceError: Cannot access 'x' before initialization + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-meth-eval-var-scope-syntax-err.js +transform error: SyntaxError: Identifier 'a' has already been declared + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/expressions/object/method-definition/async-super-call-param.js +transform error: ReferenceError: _superprop_getMethod is not defined + tasks/coverage/test262/test/language/literals/regexp/u-surrogate-pairs-atom-escape-decimal.js codegen error: Test262Error: Expected SameValue(«true», «false») to be true +tasks/coverage/test262/test/language/statements/async-function/forbidden-ext/b1/async-func-decl-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/statements/async-function/forbidden-ext/b1/async-func-decl-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/statements/async-function/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/statements/async-generator/forbidden-ext/b1/async-gen-func-decl-forbidden-ext-direct-access-prop-arguments.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + +tasks/coverage/test262/test/language/statements/async-generator/forbidden-ext/b1/async-gen-func-decl-forbidden-ext-direct-access-prop-caller.js +transform error: Test262Error: Expected SameValue(«true», «false») to be true + tasks/coverage/test262/test/language/statements/async-generator/return-undefined-implicit-and-explicit.js -minify error: Test262Error: Actual [tick 1, g1 ret, g2 ret, g3 ret, g4 ret, tick 2] and expected [tick 1, g1 ret, g2 ret, tick 2, g3 ret, g4 ret] should have the same contents. Ticks for implicit and explicit return undefined +transform error: Test262Error: Actual [tick 1, tick 2, g1 ret, g2 ret, g3 ret, g4 ret] and expected [tick 1, g1 ret, g2 ret, tick 2, g3 ret, g4 ret] should have the same contents. Ticks for implicit and explicit return undefined + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-async-from-sync-iterator-inaccessible.js +transform error: TypeError: Cannot convert undefined or null to object + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-normal-notdone-iter-value-throws.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js +transform error: Test262Error: .throw should not be accessed + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-return-notdone-iter-value-throws.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js +transform error: Test262Error: Actual [start, get return, tick 1, get then, tick 2, tick 3] and expected [start, tick 1, get then, tick 2, get return, get then, tick 3] should have the same contents. Ticks for return with thenable getter + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/statements/async-generator/yield-star-throw-notdone-iter-value-throws.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/async-gen-method-static/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/statements/class/async-method/dflt-params-abrupt.js +transform error: Test262Error: + +tasks/coverage/test262/test/language/statements/class/async-method/dflt-params-ref-later.js +transform error: ReferenceError: Cannot access 'y' before initialization + +tasks/coverage/test262/test/language/statements/class/async-method/dflt-params-ref-self.js +transform error: ReferenceError: Cannot access 'x' before initialization + +tasks/coverage/test262/test/language/statements/class/async-method/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/statements/class/async-method-static/dflt-params-abrupt.js +transform error: Test262Error: + +tasks/coverage/test262/test/language/statements/class/async-method-static/dflt-params-ref-later.js +transform error: ReferenceError: Cannot access 'y' before initialization + +tasks/coverage/test262/test/language/statements/class/async-method-static/dflt-params-ref-self.js +transform error: ReferenceError: Cannot access 'x' before initialization + +tasks/coverage/test262/test/language/statements/class/async-method-static/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/statements/class/definition/methods-async-super-call-param.js +transform error: ReferenceError: _superprop_getMethod is not defined + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-async-next.js +transform error: Test262Error: Expected SameValue(«"get next done (1)"», «"get next value (1)"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-async-return.js +transform error: Test262Error: Expected SameValue(«"get return"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-async-throw.js +transform error: Test262Error: Expected SameValue(«"get throw"», «"get next"») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-call-done-get-abrupt.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-call-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-non-object-ignores-then.js +transform error: http://localhost:32055/run: Network Error: Unexpected EOF + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-then-get-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-next-then-returns-abrupt.js +transform error: Test262Error: reject reason Expected SameValue(«TypeError: The iterator does not provide a 'throw' method.», «[object Object]») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-gen-private-method-static/yield-star-sync-throw.js +transform error: throw-arg-1 + +tasks/coverage/test262/test/language/statements/class/elements/async-private-method/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/statements/class/elements/async-private-method-static/returns-async-arrow-returns-arguments-from-parent-function.js +transform error: Test262Error: Expected SameValue(«false», «true») to be true + +tasks/coverage/test262/test/language/statements/class/static-init-arguments-methods.js +transform error: Test262Error: Actual [async method] and expected [] should have the same contents. body + +tasks/coverage/test262/test/language/statements/class/subclass/superclass-async-function.js +transform error: TypeError: Cannot redefine property: prototype + +tasks/coverage/test262/test/language/statements/class/subclass/superclass-async-generator-function.js +transform error: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all + +tasks/coverage/test262/test/language/statements/for-await-of/async-from-sync-iterator-continuation-abrupt-completion-get-constructor.js +transform error: Test262Error: Actual [start, tick 1, catch, tick 2] and expected [start, tick 1, tick 2, catch] should have the same contents. + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-elem-init-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «4») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-elem-nested-array-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «22») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-elem-nested-obj-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «2») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-elem-target-yield-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «33») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-rest-nested-array-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «86») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-rest-nested-obj-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «2») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-array-rest-yield-ident-valid.js +transform error: TypeError: Cannot read properties of undefined (reading 'length') + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-obj-id-init-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «3») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-obj-prop-elem-init-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «4») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-obj-prop-elem-target-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «23») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-obj-prop-nested-array-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «22») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/async-func-decl-dstr-obj-prop-nested-obj-yield-ident-valid.js +transform error: Test262Error: Expected SameValue(«undefined», «2») to be true + +tasks/coverage/test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js +transform error: Test262Error: Actual [pre, constructor, constructor, tick 1, loop, constructor, constructor, tick 2, post] and expected [pre, constructor, tick 1, loop, constructor, tick 2, post] should have the same contents. Ticks and constructor lookups + +tasks/coverage/test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup.js +transform error: Test262Error: Actual [pre, constructor, tick 1, loop, constructor, tick 2, post] and expected [pre, tick 1, loop, tick 2, post] should have the same contents. Ticks and constructor lookups + +tasks/coverage/test262/test/language/statements/for-await-of/ticks-with-sync-iter-resolved-promise-and-constructor-lookup.js +transform error: Test262Error: Actual [pre, constructor, constructor, constructor, constructor, tick 1, tick 2, loop, constructor, constructor, constructor, tick 3, tick 4, post] and expected [pre, constructor, constructor, tick 1, tick 2, loop, constructor, tick 3, tick 4, post] should have the same contents. Ticks and constructor lookups tasks/coverage/test262/test/language/statements/for-of/string-astral-truncated.js codegen error: Test262Error: Expected SameValue(«"\\"», «"\\ud801"») to be true From ea9ca8ab10a05e43aa72f014632876e6b7f6bbd1 Mon Sep 17 00:00:00 2001 From: Song Gao <158983297@qq.com> Date: Fri, 15 Nov 2024 18:55:03 +0800 Subject: [PATCH 12/27] fix(just): make submodules work on windows (#7290) Fix #7282 - Change default shell to powershell 7(pwsh) to supports "&&" - change url from git protocol to https protocol. This does not need a public token(I do not know what it is...). - specify different submodule init command for windows Co-authored-by: Song Gao <songgao@microsoft.com> --- justfile | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/justfile b/justfile index bf68103913aedb..578ffb79b0a6cd 100755 --- a/justfile +++ b/justfile @@ -1,6 +1,6 @@ #!/usr/bin/env -S just --justfile -set windows-shell := ["powershell"] +set windows-shell := ["pwsh", "-NoLogo", "-Command"] set shell := ["bash", "-cu"] _default: @@ -32,10 +32,10 @@ ready: # Clone or update submodules submodules: - just clone-submodule tasks/coverage/test262 git@github.com:tc39/test262.git 0645461999632a17426e45d044ee519a0f07d022 - just clone-submodule tasks/coverage/babel git@github.com:babel/babel.git d20b314c14533ab86351ecf6ca6b7296b66a57b3 - just clone-submodule tasks/coverage/typescript git@github.com:microsoft/TypeScript.git df9d16503f6755dd071e4c591b9d21c39d03d95e - just clone-submodule tasks/prettier_conformance/prettier git@github.com:prettier/prettier.git 52829385bcc4d785e58ae2602c0b098a643523c9 + just clone-submodule tasks/coverage/test262 https://github.com/tc39/test262.git 0645461999632a17426e45d044ee519a0f07d022 + just clone-submodule tasks/coverage/babel https://github.com/babel/babel.git d20b314c14533ab86351ecf6ca6b7296b66a57b3 + just clone-submodule tasks/coverage/typescript https://github.com/microsoft/TypeScript.git df9d16503f6755dd071e4c591b9d21c39d03d95e + just clone-submodule tasks/prettier_conformance/prettier https://github.com/prettier/prettier.git 52829385bcc4d785e58ae2602c0b098a643523c9 # Install git pre-commit to format files install-hook: @@ -193,10 +193,18 @@ new-security-rule name: cargo run -p rulegen {{name}} security clone-submodule dir url sha: - cd {{dir}} || git init {{dir}} - cd {{dir}} && git remote add origin {{url}} || true + just git-init-if-not-exist {{dir}} + cd {{dir}} && git remote add origin {{url}} cd {{dir}} && git fetch --depth=1 origin {{sha}} && git reset --hard {{sha}} +[unix] +git-init-if-not-exist dir: + cd {{dir}} || git init {{dir}} + +[windows] +git-init-if-not-exist dir: + if (Test-Path {{ dir }}) {cd {{ dir }}} else {git init {{dir}}} + website path: cargo run -p website -- linter-rules --table {{path}}/src/docs/guide/usage/linter/generated-rules.md --rule-docs {{path}}/src/docs/guide/usage/linter/rules cargo run -p website -- linter-cli > {{path}}/src/docs/guide/usage/linter/generated-cli.md From f4213b8d12ae23c539001990b8a1f70483fa6e8b Mon Sep 17 00:00:00 2001 From: overlookmotel <theoverlookmotel@gmail.com> Date: Fri, 15 Nov 2024 16:02:54 +0000 Subject: [PATCH 13/27] fix(tools): `just test-transform` run conformance only once (#7295) `--exec` flag also runs the non-exec tests, so it's not required to run it twice. --- justfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/justfile b/justfile index 578ffb79b0a6cd..a3352e17604148 100755 --- a/justfile +++ b/justfile @@ -128,8 +128,7 @@ autoinherit: # Test Transform test-transform *args='': - cargo run -p oxc_transform_conformance -- {{args}} - cargo run -p oxc_transform_conformance -- --exec {{args}} + cargo run -p oxc_transform_conformance -- --exec {{args}} # Install wasm-pack install-wasm: From 16cfb96a796564b65783d2e2d3f60f451fd64e69 Mon Sep 17 00:00:00 2001 From: dalaoshu <laipichan@qq.com> Date: Sat, 16 Nov 2024 00:03:23 +0800 Subject: [PATCH 14/27] fix(justfile): make submodules work on windows (#7293) Related to #7290, closes #7296 By default, `Windows` encounters the following issue unless the user installs `PowerShell 7` (pwsh). ```bash error: Recipe `submodules` could not be run because just could not find the shell: program not found error: Recipe `init` could not be run because just could not find the shell: program not found ``` Furthermore, I have found a better way to solve this problem. --- justfile | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/justfile b/justfile index a3352e17604148..9419c85c696c2c 100755 --- a/justfile +++ b/justfile @@ -1,6 +1,6 @@ #!/usr/bin/env -S just --justfile -set windows-shell := ["pwsh", "-NoLogo", "-Command"] +set windows-shell := ["powershell.exe", "-NoLogo", "-Command"] set shell := ["bash", "-cu"] _default: @@ -191,18 +191,17 @@ new-vitest-rule name: new-security-rule name: cargo run -p rulegen {{name}} security -clone-submodule dir url sha: - just git-init-if-not-exist {{dir}} - cd {{dir}} && git remote add origin {{url}} - cd {{dir}} && git fetch --depth=1 origin {{sha}} && git reset --hard {{sha}} - [unix] -git-init-if-not-exist dir: +clone-submodule dir url sha: cd {{dir}} || git init {{dir}} + cd {{dir}} && git remote add origin {{url}} || true + cd {{dir}} && git fetch --depth=1 origin {{sha}} && git reset --hard {{sha}} [windows] -git-init-if-not-exist dir: - if (Test-Path {{ dir }}) {cd {{ dir }}} else {git init {{dir}}} +clone-submodule dir url sha: + if (-not (Test-Path {{dir}}/.git)) { git init {{dir}} } + cd {{dir}} ; if ((git remote) -notcontains 'origin') { git remote add origin {{url}} } else { git remote set-url origin {{url}} } + cd {{dir}} ; git fetch --depth=1 origin {{sha}} ; git reset --hard {{sha}} website path: cargo run -p website -- linter-rules --table {{path}}/src/docs/guide/usage/linter/generated-rules.md --rule-docs {{path}}/src/docs/guide/usage/linter/rules From a0766e6a7ff55c88f989c68ffe20df1a25ad1d9a Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:04:02 +0000 Subject: [PATCH 15/27] fix(codegen): fix arithmetic overflow printing unspanned nodes (#7292) Similar to #7289. Check if `span.end` is 0 before doing `span.end - 1`, to prevent arithmetic overflow. Also changed all checks to `span.end > 0`, just for consistency. --- crates/oxc_codegen/src/gen.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 3568417077daf9..06b29c25748bcd 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -665,7 +665,7 @@ impl<'a> Gen for Function<'a> { impl<'a> Gen for FunctionBody<'a> { fn gen(&self, p: &mut Codegen, ctx: Context) { let span_end = self.span.end; - let comments_at_end = if !p.options.minify && span_end != 0 { + let comments_at_end = if !p.options.minify && span_end > 0 { p.get_statement_comments(span_end - 1) } else { None @@ -1985,7 +1985,7 @@ impl<'a> GenExpr for ImportExpression<'a> { } if has_comment { // Handle `/* comment */);` - if !p.print_expr_comments(self.span.end - 1) { + if self.span.end > 0 && !p.print_expr_comments(self.span.end - 1) { p.print_soft_newline(); } p.dedent(); @@ -2067,13 +2067,13 @@ impl<'a> GenExpr for NewExpression<'a> { p.print_str("new "); self.callee.print_expr(p, Precedence::New, Context::FORBID_CALL); p.print_ascii_byte(b'('); - let has_comment = (!self.span.is_unspanned() && p.has_comment(self.span.end - 1)) + let has_comment = (self.span.end > 0 && p.has_comment(self.span.end - 1)) || self.arguments.iter().any(|item| p.has_comment(item.span().start)); if has_comment { p.indent(); p.print_list_with_comments(&self.arguments, ctx); // Handle `/* comment */);` - if !p.print_expr_comments(self.span.end - 1) { + if self.span.end > 0 && !p.print_expr_comments(self.span.end - 1) { p.print_soft_newline(); } p.dedent(); From 1cbc624a8bf86cacfbf79725031f616b7f1d3343 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:44:08 +0000 Subject: [PATCH 16/27] refactor(traverse)!: rename `TraverseCtx` methods for creating `IdentifierReference`s (#7300) `create_reference_id` was a confusing name, as it doesn't return a `ReferenceId`. Rename these methods to more clearly represent what they do. --- .../src/common/helper_loader.rs | 8 ++- .../src/common/module_imports.rs | 2 +- .../src/es2016/exponentiation_operator.rs | 69 ++++++++++--------- .../src/es2017/async_to_generator.rs | 10 ++- .../src/es2018/object_rest_spread.rs | 2 +- .../es2021/logical_assignment_operators.rs | 2 +- crates/oxc_transformer/src/jsx/refresh.rs | 4 +- crates/oxc_transformer/src/regexp/mod.rs | 2 +- crates/oxc_transformer/src/typescript/enum.rs | 4 +- .../src/context/bound_identifier.rs | 2 +- .../src/context/maybe_bound_identifier.rs | 2 +- crates/oxc_traverse/src/context/mod.rs | 14 ++-- 12 files changed, 67 insertions(+), 54 deletions(-) diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 555491703b1749..0346c988765ff0 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -277,8 +277,12 @@ impl<'a> HelperLoaderStore<'a> { static HELPER_VAR: &str = "babelHelpers"; let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), HELPER_VAR); - let ident = - ctx.create_reference_id(SPAN, Atom::from(HELPER_VAR), symbol_id, ReferenceFlags::Read); + let ident = ctx.create_ident_reference( + SPAN, + Atom::from(HELPER_VAR), + symbol_id, + ReferenceFlags::Read, + ); let object = Expression::Identifier(ctx.alloc(ident)); let property = ctx.ast.identifier_name(SPAN, Atom::from(helper.name())); Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false)) diff --git a/crates/oxc_transformer/src/common/module_imports.rs b/crates/oxc_transformer/src/common/module_imports.rs index 96d66e0e85b561..055849832c546a 100644 --- a/crates/oxc_transformer/src/common/module_imports.rs +++ b/crates/oxc_transformer/src/common/module_imports.rs @@ -227,7 +227,7 @@ impl<'a> ModuleImportsStore<'a> { ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { let var_kind = VariableDeclarationKind::Var; - let ident = ctx.create_reference_id( + let ident = ctx.create_ident_reference( SPAN, Atom::from("require"), require_symbol_id, diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index d489405afb257c..2d787d592135b2 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -155,31 +155,30 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { // Make sure side-effects of evaluating `left` only happen once let reference = ctx.scoping.symbols_mut().get_reference_mut(ident.reference_id()); - let pow_left = - if let Some(symbol_id) = reference.symbol_id() { - // This variable is declared in scope so evaluating it multiple times can't trigger a getter. - // No need for a temp var. - // `left **= right` is being transformed to `left = Math.pow(left, right)`, - // so if `left` is no longer being read from, update its `ReferenceFlags`. - if matches!(ctx.ancestry.parent(), Ancestor::ExpressionStatementExpression(_)) { - *reference.flags_mut() = ReferenceFlags::Write; - } + let pow_left = if let Some(symbol_id) = reference.symbol_id() { + // This variable is declared in scope so evaluating it multiple times can't trigger a getter. + // No need for a temp var. + // `left **= right` is being transformed to `left = Math.pow(left, right)`, + // so if `left` is no longer being read from, update its `ReferenceFlags`. + if matches!(ctx.ancestry.parent(), Ancestor::ExpressionStatementExpression(_)) { + *reference.flags_mut() = ReferenceFlags::Write; + } - Expression::Identifier(ctx.ast.alloc(ctx.create_bound_reference_id( - SPAN, - ident.name.clone(), - symbol_id, - ReferenceFlags::Read, - ))) - } else { - // Unbound reference. Could possibly trigger a getter so we need to only evaluate it once. - // Assign to a temp var. - let reference = Expression::Identifier(ctx.ast.alloc( - ctx.create_unbound_reference_id(SPAN, ident.name.clone(), ReferenceFlags::Read), - )); - let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx); - binding.create_read_expression(ctx) - }; + Expression::Identifier(ctx.ast.alloc(ctx.create_bound_ident_reference( + SPAN, + ident.name.clone(), + symbol_id, + ReferenceFlags::Read, + ))) + } else { + // Unbound reference. Could possibly trigger a getter so we need to only evaluate it once. + // Assign to a temp var. + let reference = Expression::Identifier(ctx.ast.alloc( + ctx.create_unbound_ident_reference(SPAN, ident.name.clone(), ReferenceFlags::Read), + )); + let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx); + binding.create_read_expression(ctx) + }; (pow_left, temp_var_inits) } @@ -496,12 +495,14 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { if let Some(symbol_id) = symbol_id { // This variable is declared in scope so evaluating it multiple times can't trigger a getter. // No need for a temp var. - return Expression::Identifier(ctx.ast.alloc(ctx.create_bound_reference_id( - SPAN, - ident.name.clone(), - symbol_id, - ReferenceFlags::Read, - ))); + return Expression::Identifier(ctx.ast.alloc( + ctx.create_bound_ident_reference( + SPAN, + ident.name.clone(), + symbol_id, + ReferenceFlags::Read, + ), + )); } // Unbound reference. Could possibly trigger a getter so we need to only evaluate it once. // Assign to a temp var. @@ -547,8 +548,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let math_symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Math"); - let ident_math = - ctx.create_reference_id(SPAN, Atom::from("Math"), math_symbol_id, ReferenceFlags::Read); + let ident_math = ctx.create_ident_reference( + SPAN, + Atom::from("Math"), + math_symbol_id, + ReferenceFlags::Read, + ); let object = Expression::Identifier(ctx.alloc(ident_math)); let property = ctx.ast.identifier_name(SPAN, "pow"); let callee = diff --git a/crates/oxc_transformer/src/es2017/async_to_generator.rs b/crates/oxc_transformer/src/es2017/async_to_generator.rs index 9ebcb42db1b618..f8fe6520374c19 100644 --- a/crates/oxc_transformer/src/es2017/async_to_generator.rs +++ b/crates/oxc_transformer/src/es2017/async_to_generator.rs @@ -310,7 +310,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { let id = caller_function.id.as_ref().unwrap(); // If the function has an id, then we need to return the id. // `function foo() { ... }` -> `function foo() {} return foo;` - let reference = ctx.create_bound_reference_id( + let reference = ctx.create_bound_ident_reference( SPAN, id.name.clone(), id.symbol_id(), @@ -597,8 +597,12 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "arguments"); - let arguments_ident = - ctx.create_reference_id(SPAN, Atom::from("arguments"), symbol_id, ReferenceFlags::Read); + let arguments_ident = ctx.create_ident_reference( + SPAN, + Atom::from("arguments"), + symbol_id, + ReferenceFlags::Read, + ); let arguments_ident = Argument::Identifier(ctx.alloc(arguments_ident)); // (this, arguments) diff --git a/crates/oxc_transformer/src/es2018/object_rest_spread.rs b/crates/oxc_transformer/src/es2018/object_rest_spread.rs index cb20c5e093abbd..de17587cafea45 100644 --- a/crates/oxc_transformer/src/es2018/object_rest_spread.rs +++ b/crates/oxc_transformer/src/es2018/object_rest_spread.rs @@ -142,7 +142,7 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> { fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> { let ident = - ctx.create_reference_id(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read); + ctx.create_ident_reference(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read); let object = Expression::Identifier(ctx.alloc(ident)); let property = ctx.ast.identifier_name(SPAN, Atom::from("assign")); Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false)) diff --git a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs index 94697914f44827..e2e8fbf4f491de 100644 --- a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs +++ b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs @@ -134,7 +134,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> { let symbol_id = reference.symbol_id(); let left_expr = Expression::Identifier(ctx.alloc(ident.clone())); - let ident = ctx.create_reference_id( + let ident = ctx.create_ident_reference( SPAN, ident.name.clone(), symbol_id, diff --git a/crates/oxc_transformer/src/jsx/refresh.rs b/crates/oxc_transformer/src/jsx/refresh.rs index 4e13e1f60f91e8..adfa56b2065a76 100644 --- a/crates/oxc_transformer/src/jsx/refresh.rs +++ b/crates/oxc_transformer/src/jsx/refresh.rs @@ -336,7 +336,7 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> { binding_name.as_str(), ) .map(|symbol_id| { - let ident = ctx.create_bound_reference_id( + let ident = ctx.create_bound_ident_reference( SPAN, binding_name, symbol_id, @@ -496,7 +496,7 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { let left = self.create_registration(id.name.clone(), ReferenceFlags::Write, ctx); - let right = ctx.create_bound_reference_id( + let right = ctx.create_bound_ident_reference( SPAN, id.name.clone(), id.symbol_id(), diff --git a/crates/oxc_transformer/src/regexp/mod.rs b/crates/oxc_transformer/src/regexp/mod.rs index a2dfe6c03c2ebd..bf1b816b1946b8 100644 --- a/crates/oxc_transformer/src/regexp/mod.rs +++ b/crates/oxc_transformer/src/regexp/mod.rs @@ -180,7 +180,7 @@ impl<'a, 'ctx> Traverse<'a> for RegExp<'a, 'ctx> { let callee = { let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "RegExp"); - let ident = ctx.create_reference_id( + let ident = ctx.create_ident_reference( SPAN, Atom::from("RegExp"), symbol_id, diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index 5866d4b8325f85..708aeacf375b1d 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -122,7 +122,7 @@ impl<'a> TypeScriptEnum<'a> { } else { // }(Foo || {}); let op = LogicalOperator::Or; - let left = ctx.create_bound_reference_id( + let left = ctx.create_bound_ident_reference( decl.id.span, enum_name.clone(), var_symbol_id, @@ -138,7 +138,7 @@ impl<'a> TypeScriptEnum<'a> { if is_already_declared { let op = AssignmentOperator::Assign; - let left = ctx.create_bound_reference_id( + let left = ctx.create_bound_ident_reference( decl.id.span, enum_name.clone(), var_symbol_id, diff --git a/crates/oxc_traverse/src/context/bound_identifier.rs b/crates/oxc_traverse/src/context/bound_identifier.rs index 2761a89c80b09a..5fbaa063b32091 100644 --- a/crates/oxc_traverse/src/context/bound_identifier.rs +++ b/crates/oxc_traverse/src/context/bound_identifier.rs @@ -236,7 +236,7 @@ impl<'a> BoundIdentifier<'a> { flags: ReferenceFlags, ctx: &mut TraverseCtx<'a>, ) -> IdentifierReference<'a> { - ctx.create_bound_reference_id(span, self.name.clone(), self.symbol_id, flags) + ctx.create_bound_ident_reference(span, self.name.clone(), self.symbol_id, flags) } /// Create `Expression::Identifier` referencing this binding, with specified `Span` and `ReferenceFlags` diff --git a/crates/oxc_traverse/src/context/maybe_bound_identifier.rs b/crates/oxc_traverse/src/context/maybe_bound_identifier.rs index 5d7b010f717dff..6dc1451ccf3eda 100644 --- a/crates/oxc_traverse/src/context/maybe_bound_identifier.rs +++ b/crates/oxc_traverse/src/context/maybe_bound_identifier.rs @@ -218,7 +218,7 @@ impl<'a> MaybeBoundIdentifier<'a> { flags: ReferenceFlags, ctx: &mut TraverseCtx<'a>, ) -> IdentifierReference<'a> { - ctx.create_reference_id(span, self.name.clone(), self.symbol_id, flags) + ctx.create_ident_reference(span, self.name.clone(), self.symbol_id, flags) } /// Create `Expression::Identifier` referencing this binding, with specified `Span` and `ReferenceFlags` diff --git a/crates/oxc_traverse/src/context/mod.rs b/crates/oxc_traverse/src/context/mod.rs index ac2968dcddfdeb..c9b735bff0ee92 100644 --- a/crates/oxc_traverse/src/context/mod.rs +++ b/crates/oxc_traverse/src/context/mod.rs @@ -434,7 +434,7 @@ impl<'a> TraverseCtx<'a> { } /// Create an `IdentifierReference` bound to a `SymbolId`. - pub fn create_bound_reference_id( + pub fn create_bound_ident_reference( &mut self, span: Span, name: Atom<'a>, @@ -458,7 +458,7 @@ impl<'a> TraverseCtx<'a> { } /// Create an unbound `IdentifierReference`. - pub fn create_unbound_reference_id( + pub fn create_unbound_ident_reference( &mut self, span: Span, name: Atom<'a>, @@ -486,9 +486,9 @@ impl<'a> TraverseCtx<'a> { /// Create an `IdentifierReference` optionally bound to a `SymbolId`. /// - /// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_reference_id` - /// or `TraverseCtx::create_unbound_reference_id`. - pub fn create_reference_id( + /// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_ident_reference` + /// or `TraverseCtx::create_unbound_ident_reference`. + pub fn create_ident_reference( &mut self, span: Span, name: Atom<'a>, @@ -496,9 +496,9 @@ impl<'a> TraverseCtx<'a> { flags: ReferenceFlags, ) -> IdentifierReference<'a> { if let Some(symbol_id) = symbol_id { - self.create_bound_reference_id(span, name, symbol_id, flags) + self.create_bound_ident_reference(span, name, symbol_id, flags) } else { - self.create_unbound_reference_id(span, name, flags) + self.create_unbound_ident_reference(span, name, flags) } } From ba0b2ff85622bf0485c1bd6993c23ba4cb48e0b0 Mon Sep 17 00:00:00 2001 From: "Alexander S." <sysix@sysix-coding.de> Date: Sat, 16 Nov 2024 06:34:44 +0100 Subject: [PATCH 17/27] fix(editor): reload workspace configuration after change (#7302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit after changing `settings.json`, the changes whould not to updated internally. With this PR the updated values get passed to the language-server. 🥳 probably closes https://github.com/oxc-project/backlog/issues/132 because we also support the oxlint config --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- editors/vscode/client/config.ts | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/editors/vscode/client/config.ts b/editors/vscode/client/config.ts index ba553afb13a91d..d2eabe94ec753c 100644 --- a/editors/vscode/client/config.ts +++ b/editors/vscode/client/config.ts @@ -4,11 +4,11 @@ import { IDisposable } from './types'; export class ConfigService implements Config, IDisposable { private static readonly _namespace = 'oxc'; private readonly _disposables: IDisposable[] = []; - private _inner: WorkspaceConfiguration; - private _runTrigger: Trigger; - private _enable: boolean; - private _trace: TraceLevel; - private _configPath: string; + private _inner!: WorkspaceConfiguration; + private _runTrigger!: Trigger; + private _enable!: boolean; + private _trace!: TraceLevel; + private _configPath!: string; private _binPath: string | undefined; public onConfigChange: @@ -16,12 +16,7 @@ export class ConfigService implements Config, IDisposable { | undefined; constructor() { - this._inner = workspace.getConfiguration(ConfigService._namespace); - this._runTrigger = this._inner.get<Trigger>('lint.run') || 'onType'; - this._enable = this._inner.get<boolean>('enable') ?? true; - this._trace = this._inner.get<TraceLevel>('trace.server') || 'off'; - this._configPath = this._inner.get<string>('configPath') || '.eslintrc'; - this._binPath = this._inner.get<string>('path.server'); + this.setSettingsFromWorkspace(); this.onConfigChange = undefined; const disposeChangeListener = workspace.onDidChangeConfiguration( @@ -30,6 +25,16 @@ export class ConfigService implements Config, IDisposable { this._disposables.push(disposeChangeListener); } + private setSettingsFromWorkspace(): void { + this._inner = workspace.getConfiguration(ConfigService._namespace); + + this._runTrigger = this._inner.get<Trigger>('lint.run') || 'onType'; + this._enable = this._inner.get<boolean>('enable') ?? true; + this._trace = this._inner.get<TraceLevel>('trace.server') || 'off'; + this._configPath = this._inner.get<string>('configPath') || '.eslintrc'; + this._binPath = this._inner.get<string>('path.server'); + } + get runTrigger(): Trigger { return this._runTrigger; } @@ -87,11 +92,7 @@ export class ConfigService implements Config, IDisposable { private onVscodeConfigChange(event: ConfigurationChangeEvent): void { if (event.affectsConfiguration(ConfigService._namespace)) { - this._runTrigger = this._inner.get<Trigger>('lint.run') || 'onType'; - this._enable = this._inner.get<boolean>('enable') ?? true; - this._trace = this._inner.get<TraceLevel>('trace.server') || 'off'; - this._configPath = this._inner.get<string>('configPath') || '.eslintrc'; - this._binPath = this._inner.get<string>('path.server'); + this.setSettingsFromWorkspace(); this.onConfigChange?.call(this, event); } } From faf8dde4ffc30a1dce5566d8c7a51f63283b01ca Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:36:35 +0000 Subject: [PATCH 18/27] feat(traverse): add methods for creating `Expression::Identifier`s (#7301) It's a common pattern in transformer to call `ctx.create_ident_reference()` and then convert to an `Expression` with `Expression::Identifier(ctx.ast.alloc(ident))`. Add methods to do this in a single method call. --- .../src/common/helper_loader.rs | 9 +--- .../src/common/module_imports.rs | 5 +-- .../src/es2016/exponentiation_operator.rs | 35 +++++----------- .../src/es2017/async_to_generator.rs | 10 ++--- .../src/es2018/object_rest_spread.rs | 5 +-- crates/oxc_transformer/src/jsx/refresh.rs | 6 +-- crates/oxc_transformer/src/regexp/mod.rs | 8 +--- crates/oxc_transformer/src/typescript/enum.rs | 3 +- crates/oxc_traverse/src/context/mod.rs | 41 +++++++++++++++++++ 9 files changed, 66 insertions(+), 56 deletions(-) diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 0346c988765ff0..79e42f246dee56 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -277,13 +277,8 @@ impl<'a> HelperLoaderStore<'a> { static HELPER_VAR: &str = "babelHelpers"; let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), HELPER_VAR); - let ident = ctx.create_ident_reference( - SPAN, - Atom::from(HELPER_VAR), - symbol_id, - ReferenceFlags::Read, - ); - let object = Expression::Identifier(ctx.alloc(ident)); + let object = + ctx.create_ident_expr(SPAN, Atom::from(HELPER_VAR), symbol_id, ReferenceFlags::Read); let property = ctx.ast.identifier_name(SPAN, Atom::from(helper.name())); Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false)) } diff --git a/crates/oxc_transformer/src/common/module_imports.rs b/crates/oxc_transformer/src/common/module_imports.rs index 055849832c546a..94c4c2a1830b21 100644 --- a/crates/oxc_transformer/src/common/module_imports.rs +++ b/crates/oxc_transformer/src/common/module_imports.rs @@ -226,14 +226,12 @@ impl<'a> ModuleImportsStore<'a> { require_symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { - let var_kind = VariableDeclarationKind::Var; - let ident = ctx.create_ident_reference( + let callee = ctx.create_ident_expr( SPAN, Atom::from("require"), require_symbol_id, ReferenceFlags::read(), ); - let callee = Expression::Identifier(ctx.alloc(ident)); let args = { let arg = Argument::from(ctx.ast.expression_string_literal(SPAN, source)); @@ -241,6 +239,7 @@ impl<'a> ModuleImportsStore<'a> { }; let Some(Import::Default(local)) = names.into_iter().next() else { unreachable!() }; let id = local.create_binding_pattern(ctx); + let var_kind = VariableDeclarationKind::Var; let decl = { let init = ctx.ast.expression_call(SPAN, callee, NONE, args, false); let decl = ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false); diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index 2d787d592135b2..716ade8cf25dd4 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -164,18 +164,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { *reference.flags_mut() = ReferenceFlags::Write; } - Expression::Identifier(ctx.ast.alloc(ctx.create_bound_ident_reference( - SPAN, - ident.name.clone(), - symbol_id, - ReferenceFlags::Read, - ))) + ctx.create_bound_ident_expr(SPAN, ident.name.clone(), symbol_id, ReferenceFlags::Read) } else { // Unbound reference. Could possibly trigger a getter so we need to only evaluate it once. // Assign to a temp var. - let reference = Expression::Identifier(ctx.ast.alloc( - ctx.create_unbound_ident_reference(SPAN, ident.name.clone(), ReferenceFlags::Read), - )); + let reference = + ctx.create_unbound_ident_expr(SPAN, ident.name.clone(), ReferenceFlags::Read); let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx); binding.create_read_expression(ctx) }; @@ -495,14 +489,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { if let Some(symbol_id) = symbol_id { // This variable is declared in scope so evaluating it multiple times can't trigger a getter. // No need for a temp var. - return Expression::Identifier(ctx.ast.alloc( - ctx.create_bound_ident_reference( - SPAN, - ident.name.clone(), - symbol_id, - ReferenceFlags::Read, - ), - )); + return ctx.create_bound_ident_expr( + SPAN, + ident.name.clone(), + symbol_id, + ReferenceFlags::Read, + ); } // Unbound reference. Could possibly trigger a getter so we need to only evaluate it once. // Assign to a temp var. @@ -548,13 +540,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let math_symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Math"); - let ident_math = ctx.create_ident_reference( - SPAN, - Atom::from("Math"), - math_symbol_id, - ReferenceFlags::Read, - ); - let object = Expression::Identifier(ctx.alloc(ident_math)); + let object = + ctx.create_ident_expr(SPAN, Atom::from("Math"), math_symbol_id, ReferenceFlags::Read); let property = ctx.ast.identifier_name(SPAN, "pow"); let callee = Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false)); diff --git a/crates/oxc_transformer/src/es2017/async_to_generator.rs b/crates/oxc_transformer/src/es2017/async_to_generator.rs index f8fe6520374c19..97cfab30326d73 100644 --- a/crates/oxc_transformer/src/es2017/async_to_generator.rs +++ b/crates/oxc_transformer/src/es2017/async_to_generator.rs @@ -310,7 +310,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { let id = caller_function.id.as_ref().unwrap(); // If the function has an id, then we need to return the id. // `function foo() { ... }` -> `function foo() {} return foo;` - let reference = ctx.create_bound_ident_reference( + let reference = ctx.create_bound_ident_expr( SPAN, id.name.clone(), id.symbol_id(), @@ -318,8 +318,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { ); let statement = Statement::FunctionDeclaration(caller_function); statements.push(statement); - let argument = Some(Expression::Identifier(ctx.alloc(reference))); - statements.push(ctx.ast.statement_return(SPAN, argument)); + statements.push(ctx.ast.statement_return(SPAN, Some(reference))); } else { // If the function doesn't have an id, then we need to return the function itself. // `function() { ... }` -> `return function() { ... };` @@ -597,13 +596,12 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "arguments"); - let arguments_ident = ctx.create_ident_reference( + let arguments_ident = Argument::from(ctx.create_ident_expr( SPAN, Atom::from("arguments"), symbol_id, ReferenceFlags::Read, - ); - let arguments_ident = Argument::Identifier(ctx.alloc(arguments_ident)); + )); // (this, arguments) let mut arguments = ctx.ast.vec_with_capacity(2); diff --git a/crates/oxc_transformer/src/es2018/object_rest_spread.rs b/crates/oxc_transformer/src/es2018/object_rest_spread.rs index de17587cafea45..0daaf88ca3aa2c 100644 --- a/crates/oxc_transformer/src/es2018/object_rest_spread.rs +++ b/crates/oxc_transformer/src/es2018/object_rest_spread.rs @@ -141,9 +141,8 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> { } fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> { - let ident = - ctx.create_ident_reference(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read); - let object = Expression::Identifier(ctx.alloc(ident)); + let object = + ctx.create_ident_expr(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read); let property = ctx.ast.identifier_name(SPAN, Atom::from("assign")); Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false)) } diff --git a/crates/oxc_transformer/src/jsx/refresh.rs b/crates/oxc_transformer/src/jsx/refresh.rs index adfa56b2065a76..0598d5150719e5 100644 --- a/crates/oxc_transformer/src/jsx/refresh.rs +++ b/crates/oxc_transformer/src/jsx/refresh.rs @@ -336,13 +336,12 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> { binding_name.as_str(), ) .map(|symbol_id| { - let ident = ctx.create_bound_ident_reference( + let mut expr = ctx.create_bound_ident_expr( SPAN, binding_name, symbol_id, ReferenceFlags::Read, ); - let mut expr = Expression::Identifier(ctx.alloc(ident)); if is_member_expression { // binding_name.hook_name @@ -496,13 +495,12 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> Statement<'a> { let left = self.create_registration(id.name.clone(), ReferenceFlags::Write, ctx); - let right = ctx.create_bound_ident_reference( + let right = ctx.create_bound_ident_expr( SPAN, id.name.clone(), id.symbol_id(), ReferenceFlags::Read, ); - let right = Expression::Identifier(ctx.alloc(right)); let expr = ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, left, right); ctx.ast.statement_expression(SPAN, expr) } diff --git a/crates/oxc_transformer/src/regexp/mod.rs b/crates/oxc_transformer/src/regexp/mod.rs index bf1b816b1946b8..fdb69fdb00746c 100644 --- a/crates/oxc_transformer/src/regexp/mod.rs +++ b/crates/oxc_transformer/src/regexp/mod.rs @@ -180,13 +180,7 @@ impl<'a, 'ctx> Traverse<'a> for RegExp<'a, 'ctx> { let callee = { let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "RegExp"); - let ident = ctx.create_ident_reference( - SPAN, - Atom::from("RegExp"), - symbol_id, - ReferenceFlags::read(), - ); - Expression::Identifier(ctx.alloc(ident)) + ctx.create_ident_expr(SPAN, Atom::from("RegExp"), symbol_id, ReferenceFlags::read()) }; let mut arguments = ctx.ast.vec_with_capacity(2); diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index 708aeacf375b1d..b503f9ff327040 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -122,13 +122,12 @@ impl<'a> TypeScriptEnum<'a> { } else { // }(Foo || {}); let op = LogicalOperator::Or; - let left = ctx.create_bound_ident_reference( + let left = ctx.create_bound_ident_expr( decl.id.span, enum_name.clone(), var_symbol_id, ReferenceFlags::Read, ); - let left = Expression::Identifier(ctx.alloc(left)); let right = ast.expression_object(SPAN, ast.vec(), None); let expression = ast.expression_logical(SPAN, left, op, right); ast.vec1(Argument::from(expression)) diff --git a/crates/oxc_traverse/src/context/mod.rs b/crates/oxc_traverse/src/context/mod.rs index c9b735bff0ee92..eda09ba266cc6c 100644 --- a/crates/oxc_traverse/src/context/mod.rs +++ b/crates/oxc_traverse/src/context/mod.rs @@ -445,6 +445,18 @@ impl<'a> TraverseCtx<'a> { self.ast.identifier_reference_with_reference_id(span, name, reference_id) } + /// Create an `Expression::Identifier` bound to a `SymbolId`. + pub fn create_bound_ident_expr( + &mut self, + span: Span, + name: Atom<'a>, + symbol_id: SymbolId, + flags: ReferenceFlags, + ) -> Expression<'a> { + let ident = self.create_bound_ident_reference(span, name, symbol_id, flags); + Expression::Identifier(self.ast.alloc(ident)) + } + /// Create an unbound reference. /// /// This is a shortcut for `ctx.scoping.create_unbound_reference`. @@ -468,6 +480,17 @@ impl<'a> TraverseCtx<'a> { self.ast.identifier_reference_with_reference_id(span, name, reference_id) } + /// Create an unbound `Expression::Identifier`. + pub fn create_unbound_ident_expr( + &mut self, + span: Span, + name: Atom<'a>, + flags: ReferenceFlags, + ) -> Expression<'a> { + let ident = self.create_unbound_ident_reference(span, name, flags); + Expression::Identifier(self.ast.alloc(ident)) + } + /// Create a reference optionally bound to a `SymbolId`. /// /// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_reference` @@ -502,6 +525,24 @@ impl<'a> TraverseCtx<'a> { } } + /// Create an `Expression::Identifier` optionally bound to a `SymbolId`. + /// + /// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_ident_expr` + /// or `TraverseCtx::create_unbound_ident_expr`. + pub fn create_ident_expr( + &mut self, + span: Span, + name: Atom<'a>, + symbol_id: Option<SymbolId>, + flags: ReferenceFlags, + ) -> Expression<'a> { + if let Some(symbol_id) = symbol_id { + self.create_bound_ident_expr(span, name, symbol_id, flags) + } else { + self.create_unbound_ident_expr(span, name, flags) + } + } + /// Create reference in current scope, looking up binding for `name`, /// /// This is a shortcut for `ctx.scoping.create_reference_in_current_scope`. From 4acf2db82bef84177bf39de37f417d487e6b3518 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:36:35 +0000 Subject: [PATCH 19/27] refactor(transformer): helper loader methods take `Span` (#7304) `TransformCtx::helper_call` and `TransformCtx::helper_call_expr` take a `Span`. Sometimes the helper call replaces some original code, and should have the same span as the original code. --- crates/oxc_transformer/src/common/helper_loader.rs | 8 +++++--- crates/oxc_transformer/src/es2017/async_to_generator.rs | 2 +- .../src/es2018/async_generator_functions/for_await.rs | 1 + .../src/es2018/async_generator_functions/mod.rs | 8 +++++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 79e42f246dee56..10e3a3c62452ce 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -73,7 +73,7 @@ use serde::Deserialize; use oxc_allocator::{String as ArenaString, Vec as ArenaVec}; use oxc_ast::ast::{Argument, CallExpression, Expression, TSTypeParameterInstantiation}; use oxc_semantic::{ReferenceFlags, SymbolFlags}; -use oxc_span::{Atom, SPAN}; +use oxc_span::{Atom, Span, SPAN}; use oxc_traverse::{BoundIdentifier, TraverseCtx}; use crate::TransformCtx; @@ -183,12 +183,13 @@ impl<'a> TransformCtx<'a> { pub fn helper_call( &self, helper: Helper, + span: Span, arguments: ArenaVec<'a, Argument<'a>>, ctx: &mut TraverseCtx<'a>, ) -> CallExpression<'a> { let callee = self.helper_load(helper, ctx); ctx.ast.call_expression( - SPAN, + span, callee, None::<TSTypeParameterInstantiation<'a>>, arguments, @@ -200,12 +201,13 @@ impl<'a> TransformCtx<'a> { pub fn helper_call_expr( &self, helper: Helper, + span: Span, arguments: ArenaVec<'a, Argument<'a>>, ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let callee = self.helper_load(helper, ctx); ctx.ast.expression_call( - SPAN, + span, callee, None::<TSTypeParameterInstantiation<'a>>, arguments, diff --git a/crates/oxc_transformer/src/es2017/async_to_generator.rs b/crates/oxc_transformer/src/es2017/async_to_generator.rs index 97cfab30326d73..c7107ee576cc75 100644 --- a/crates/oxc_transformer/src/es2017/async_to_generator.rs +++ b/crates/oxc_transformer/src/es2017/async_to_generator.rs @@ -639,7 +639,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> { let mut function = Self::create_function(None, params, body, scope_id, ctx); function.generator = true; let arguments = ctx.ast.vec1(Argument::FunctionExpression(function)); - self.ctx.helper_call_expr(self.helper, arguments, ctx) + self.ctx.helper_call_expr(self.helper, SPAN, arguments, ctx) } /// Creates a helper declaration statement for async-to-generator transformation. diff --git a/crates/oxc_transformer/src/es2018/async_generator_functions/for_await.rs b/crates/oxc_transformer/src/es2018/async_generator_functions/for_await.rs index b83767d63afd29..7e006971401610 100644 --- a/crates/oxc_transformer/src/es2018/async_generator_functions/for_await.rs +++ b/crates/oxc_transformer/src/es2018/async_generator_functions/for_await.rs @@ -150,6 +150,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> { let iterator = ctx.ast.move_expression(&mut stmt.right); let iterator = self.ctx.helper_call_expr( Helper::AsyncIterator, + SPAN, ctx.ast.vec1(Argument::from(iterator)), ctx, ); diff --git a/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs b/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs index 0ca70e15210a10..1b0d5c93291158 100644 --- a/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs +++ b/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs @@ -166,9 +166,11 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> { expr.argument.as_mut().map(|argument| { let argument = Argument::from(ctx.ast.move_expression(argument)); let arguments = ctx.ast.vec1(argument); - let mut argument = self.ctx.helper_call_expr(Helper::AsyncIterator, arguments, ctx); + let mut argument = + self.ctx.helper_call_expr(Helper::AsyncIterator, SPAN, arguments, ctx); let arguments = ctx.ast.vec1(Argument::from(argument)); - argument = self.ctx.helper_call_expr(Helper::AsyncGeneratorDelegate, arguments, ctx); + argument = + self.ctx.helper_call_expr(Helper::AsyncGeneratorDelegate, SPAN, arguments, ctx); ctx.ast.expression_yield(SPAN, expr.delegate, Some(argument)) }) } @@ -199,7 +201,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> { let mut argument = ctx.ast.move_expression(&mut expr.argument); let arguments = ctx.ast.vec1(Argument::from(argument)); - argument = self.ctx.helper_call_expr(Helper::AwaitAsyncGenerator, arguments, ctx); + argument = self.ctx.helper_call_expr(Helper::AwaitAsyncGenerator, SPAN, arguments, ctx); Some(ctx.ast.expression_yield(SPAN, false, Some(argument))) } From d135d3ec48b3166abb6d1bac83bab9196ce0e59e Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:36:36 +0000 Subject: [PATCH 20/27] feat(data_structures): add methods to `SparseStack` (#7305) Add methods to `SparseStack` to get the filled entries as a slice, and get their length. --- crates/oxc_data_structures/src/stack/sparse.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/oxc_data_structures/src/stack/sparse.rs b/crates/oxc_data_structures/src/stack/sparse.rs index 847d05c62f3522..9880fb4f1ca1fd 100644 --- a/crates/oxc_data_structures/src/stack/sparse.rs +++ b/crates/oxc_data_structures/src/stack/sparse.rs @@ -192,6 +192,12 @@ impl<T> SparseStack<T> { self.has_values.len() } + /// Get number of filled entries on the stack. + #[inline] + pub fn filled_len(&self) -> usize { + self.values.len() + } + /// Get capacity of stack for any entries (either `Some` or `None`). /// /// Capacity is always at least 1. Stack is never empty. @@ -209,4 +215,16 @@ impl<T> SparseStack<T> { pub fn filled_capacity(&self) -> usize { self.values.capacity() } + + /// Get filled entries of stack as a slice `&[T]`. + #[inline] + pub fn as_slice(&self) -> &[T] { + self.values.as_slice() + } + + /// Get filled entries of stack as a mutable slice `&mut [T]`. + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.values.as_mut_slice() + } } From 20d9080d59594f2ab202e7d9a8708ef4a4c0d2e8 Mon Sep 17 00:00:00 2001 From: camchenry <1514176+camchenry@users.noreply.github.com> Date: Sat, 16 Nov 2024 05:54:05 +0000 Subject: [PATCH 21/27] fix(linter)!: override plugins array when passed in config file (#7303) - fixes https://github.com/oxc-project/oxc/issues/6896 When the `plugins` config property is specified, it will overwrite the default plugins array. This allows the plugins list to be easily customized and allows for disabling default plugins at the same time as enabling non-default ones. - example: `{ "plugins": [] }` will enable no plugins. - example: `{ }` will enable default plugins. - example: `{ "plugins": ["typescript", "import"] }` will enable only the import and typescript plugins. --- crates/oxc_linter/src/config/oxlintrc.rs | 35 ++++++++++++------------ crates/oxc_linter/src/config/plugins.rs | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/crates/oxc_linter/src/config/oxlintrc.rs b/crates/oxc_linter/src/config/oxlintrc.rs index a621eddf25af03..fc96ea1b2d41b6 100644 --- a/crates/oxc_linter/src/config/oxlintrc.rs +++ b/crates/oxc_linter/src/config/oxlintrc.rs @@ -142,29 +142,28 @@ mod test { #[test] fn test_oxlintrc_de_plugins_empty_array() { let config: Oxlintrc = serde_json::from_value(json!({ "plugins": [] })).unwrap(); - assert_eq!(config.plugins, LintPlugins::default()); + assert_eq!(config.plugins, LintPlugins::empty()); } #[test] - fn test_oxlintrc_de_plugins_enabled_by_default() { - // NOTE(@DonIsaac): creating a Value with `json!` then deserializing it with serde_json::from_value - // Errs with "invalid type: string \"eslint\", expected a borrowed string" and I can't - // figure out why. This seems to work. Why??? - let configs = [ - r#"{ "plugins": ["eslint"] }"#, - r#"{ "plugins": ["oxc"] }"#, - r#"{ "plugins": ["deepscan"] }"#, // alias for oxc - ]; - // ^ these plugins are enabled by default already - for oxlintrc in configs { - let config: Oxlintrc = serde_json::from_str(oxlintrc).unwrap(); - assert_eq!(config.plugins, LintPlugins::default()); - } + fn test_oxlintrc_empty_config_plugins() { + let config: Oxlintrc = serde_json::from_str(r"{}").unwrap(); + assert_eq!(config.plugins, LintPlugins::default()); } #[test] - fn test_oxlintrc_de_plugins_new() { - let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["import"] }"#).unwrap(); - assert_eq!(config.plugins, LintPlugins::default().union(LintPlugins::IMPORT)); + fn test_oxlintrc_specifying_plugins_will_override() { + let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["react", "oxc"] }"#).unwrap(); + assert_eq!(config.plugins, LintPlugins::REACT.union(LintPlugins::OXC)); + let config: Oxlintrc = + serde_json::from_str(r#"{ "plugins": ["typescript", "unicorn"] }"#).unwrap(); + assert_eq!(config.plugins, LintPlugins::TYPESCRIPT.union(LintPlugins::UNICORN)); + let config: Oxlintrc = + serde_json::from_str(r#"{ "plugins": ["typescript", "unicorn", "react", "oxc", "import", "jsdoc", "jest", "vitest", "jsx-a11y", "nextjs", "react-perf", "promise", "node", "security"] }"#).unwrap(); + assert_eq!(config.plugins, LintPlugins::all()); + + let config: Oxlintrc = + serde_json::from_str(r#"{ "plugins": ["typescript", "@typescript-eslint"] }"#).unwrap(); + assert_eq!(config.plugins, LintPlugins::TYPESCRIPT); } } diff --git a/crates/oxc_linter/src/config/plugins.rs b/crates/oxc_linter/src/config/plugins.rs index 9099a1e55da32f..b507b32a351d22 100644 --- a/crates/oxc_linter/src/config/plugins.rs +++ b/crates/oxc_linter/src/config/plugins.rs @@ -178,7 +178,7 @@ impl<'de> Deserialize<'de> for LintPlugins { where A: de::SeqAccess<'de>, { - let mut plugins = LintPlugins::default(); + let mut plugins = LintPlugins::empty(); loop { // serde_json::from_str will provide an &str, while // serde_json::from_value provides a String. The former is From cf99be0a0d873f0c111cae9c84ef9198bcc7feca Mon Sep 17 00:00:00 2001 From: 7086cmd <54303040+7086cmd@users.noreply.github.com> Date: Sat, 16 Nov 2024 06:01:05 +0000 Subject: [PATCH 22/27] fix(minifier): do not compare bigint with object (#7294) @Boshen, could you please update the snap of runtime and commit to this PR? I want to see the effects after the unit tests are added. --- .../src/ast_passes/peephole_fold_constants.rs | 11 +++++++++-- .../peephole_substitute_alternate_syntax.rs | 2 +- tasks/coverage/snapshots/runtime.snap | 8 +------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs index 4684b17df673fa..d7397ff5c24358 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs @@ -362,14 +362,14 @@ impl<'a, 'b> PeepholeFoldConstants { } } - if matches!(left, ValueType::String | ValueType::Number) + if matches!(left, ValueType::String | ValueType::Number | ValueType::BigInt) && matches!(right, ValueType::Object) { return None; } if matches!(left, ValueType::Object) - && matches!(right, ValueType::String | ValueType::Number) + && matches!(right, ValueType::String | ValueType::Number | ValueType::BigInt) { return None; } @@ -873,6 +873,13 @@ mod test { test("'1' !== 1n", "true"); } + #[test] + fn test_object_bigint_comparison() { + test_same("{ valueOf: function() { return 0n; } } != 0n"); + test_same("0n != { valueOf: function() { return 0n; } }"); + test_same("0n != { toString: function() { return '0'; } }"); + } + #[test] fn test_nan_comparison() { test("NaN < 1", "false"); diff --git a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs index a9063cad0d13d3..381db25a375e0f 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs @@ -18,7 +18,7 @@ use crate::{node_util::Ctx, CompressorPass}; pub struct PeepholeSubstituteAlternateSyntax { /// Do not compress syntaxes that are hard to analyze inside the fixed loop. /// e.g. Do not compress `undefined -> void 0`, `true` -> `!0`. - /// Opposite of `late` in Closure Compier. + /// Opposite of `late` in Closure Compiler. in_fixed_loop: bool, // states diff --git a/tasks/coverage/snapshots/runtime.snap b/tasks/coverage/snapshots/runtime.snap index 51f7b2b1b3491c..fdf09af2d9d362 100644 --- a/tasks/coverage/snapshots/runtime.snap +++ b/tasks/coverage/snapshots/runtime.snap @@ -2,7 +2,7 @@ commit: 06454619 runtime Summary: AST Parsed : 18055/18055 (100.00%) -Positive Passed: 17796/18055 (98.57%) +Positive Passed: 17798/18055 (98.58%) tasks/coverage/test262/test/language/arguments-object/async-gen-meth-args-trailing-comma-multiple.js transform error: Test262Error: Expected SameValue(«0», «2») to be true @@ -447,12 +447,6 @@ transform error: Test262Error: Expected a TypeError to be thrown but no exceptio tasks/coverage/test262/test/language/expressions/class/heritage-async-arrow-function.js transform error: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all -tasks/coverage/test262/test/language/expressions/does-not-equals/bigint-and-object.js -minify error: Test262Error: The result of (0n != {valueOf: function() {return 0n;}}) is false Expected SameValue(«true», «false») to be true - -tasks/coverage/test262/test/language/expressions/equals/bigint-and-object.js -minify error: Test262Error: The result of (0n == {valueOf: function() {return 0n;}}) is true Expected SameValue(«false», «true») to be true - tasks/coverage/test262/test/language/expressions/exponentiation/bigint-negative-exponent-throws.js transform error: Test262Error: (-1n) ** -1n throws RangeError Expected a RangeError but got a TypeError From 4c124a86eae5a14a7258b46a76b72cb367d9781f Mon Sep 17 00:00:00 2001 From: Nicholas Rayburn <52075362+nrayburn-tech@users.noreply.github.com> Date: Sat, 16 Nov 2024 00:53:51 -0600 Subject: [PATCH 23/27] docs(editor/vscode): Update VS Code readme with installation instructions and available features (#7306) --- editors/vscode/README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/editors/vscode/README.md b/editors/vscode/README.md index c4298105aff819..8bee6d1f994eee 100644 --- a/editors/vscode/README.md +++ b/editors/vscode/README.md @@ -2,6 +2,17 @@ The Oxidation Compiler is creating a suite of high-performance tools for JavaScript and TypeScript. +## Installation + +Any of the below options can be used to install the extension. + +- Install through the VS Code extensions marketplace by searching for `Oxc`. Verify the identifier is `oxc.oxc-vscode`. +- From within VS Code, open the Quick Open (Ctrl+P or Cmd+P on macOS) and execute `ext install oxc.oxc-vscode`. + ## Oxlint -This is the linter for oxc. +This is the linter for Oxc. The currently supported features are listed below. + +- Highlighting for warnings or errors identified by Oxlint +- Quick fixes to fix a warning or error when possible +- JSON schema validation for supported Oxlint configuration files (does not include ESLint configuration files) From cf3415b0e4a77b146ca4adc36b5c00c714a8062a Mon Sep 17 00:00:00 2001 From: Song Gao <158983297@qq.com> Date: Sat, 16 Nov 2024 21:00:30 +0800 Subject: [PATCH 24/27] chore(doc): replace main/master to tag/commit to make the url always accessible (#7298) --- crates/oxc/src/napi/parse.rs | 2 +- crates/oxc/src/napi/transform.rs | 4 ++-- crates/oxc_allocator/src/boxed.rs | 2 +- crates/oxc_allocator/src/vec.rs | 2 +- crates/oxc_ast/src/ast/js.rs | 2 +- crates/oxc_ast/src/ast/ts.rs | 2 +- crates/oxc_ast/src/ast_impl/ts.rs | 2 +- crates/oxc_ast/src/generated/visit.rs | 2 +- crates/oxc_ast/src/generated/visit_mut.rs | 2 +- crates/oxc_ast/src/lib.rs | 2 +- crates/oxc_codegen/src/comment.rs | 2 +- crates/oxc_codegen/src/gen.rs | 2 +- crates/oxc_codegen/src/lib.rs | 2 +- .../oxc_codegen/tests/integration/esbuild.rs | 4 ++-- .../tests/integration/pure_comments.rs | 2 +- crates/oxc_codegen/tests/integration/unit.rs | 2 +- crates/oxc_diagnostics/src/reporter/json.rs | 2 +- crates/oxc_diagnostics/src/reporter/unix.rs | 2 +- crates/oxc_isolated_declarations/src/lib.rs | 2 +- .../tests/deno/mod.rs | 2 +- .../oxc_linter/src/config/settings/jsdoc.rs | 4 ++-- crates/oxc_linter/src/fixer/fix.rs | 4 ++-- crates/oxc_linter/src/fixer/mod.rs | 4 ++-- crates/oxc_linter/src/globals.rs | 4 ++-- .../rules/eslint/array_callback_return/mod.rs | 2 +- .../src/rules/eslint/no_control_regex.rs | 2 +- .../rules/eslint/no_empty_character_class.rs | 2 +- crates/oxc_linter/src/rules/eslint/no_eval.rs | 2 +- .../src/rules/eslint/no_obj_calls.rs | 2 +- .../src/rules/eslint/no_useless_escape.rs | 4 ++-- crates/oxc_linter/src/rules/eslint/no_var.rs | 6 ++--- crates/oxc_linter/src/rules/eslint/radix.rs | 6 ++--- crates/oxc_linter/src/rules/import/default.rs | 2 +- crates/oxc_linter/src/rules/import/export.rs | 2 +- crates/oxc_linter/src/rules/import/first.rs | 2 +- .../src/rules/import/import_no_namespace.rs | 2 +- .../src/rules/import/max_dependencies.rs | 2 +- crates/oxc_linter/src/rules/import/named.rs | 2 +- .../oxc_linter/src/rules/import/namespace.rs | 2 +- crates/oxc_linter/src/rules/import/no_amd.rs | 2 +- .../src/rules/import/no_commonjs.rs | 2 +- .../oxc_linter/src/rules/import/no_cycle.rs | 2 +- .../src/rules/import/no_deprecated.rs | 2 +- .../src/rules/import/no_duplicates.rs | 2 +- .../src/rules/import/no_named_as_default.rs | 2 +- .../import/no_named_as_default_member.rs | 2 +- .../src/rules/import/no_unused_modules.rs | 2 +- .../src/rules/import/unambiguous.rs | 2 +- .../src/rules/jest/consistent_test_it.rs | 2 +- .../src/rules/jest/expect_expect.rs | 2 +- .../src/rules/jest/no_alias_methods.rs | 2 +- .../src/rules/jest/no_commented_out_tests.rs | 2 +- .../src/rules/jest/no_conditional_expect.rs | 2 +- .../src/rules/jest/no_disabled_tests.rs | 2 +- .../src/rules/jest/no_focused_tests.rs | 2 +- .../src/rules/jest/no_identical_title.rs | 2 +- .../src/rules/jest/no_jasmine_globals.rs | 2 +- .../src/rules/jest/no_mocks_import.rs | 2 +- .../src/rules/jest/no_standalone_expect.rs | 2 +- .../src/rules/jest/no_test_prefixes.rs | 2 +- .../src/rules/jest/prefer_hooks_in_order.rs | 2 +- .../src/rules/jest/valid_describe_callback.rs | 2 +- .../oxc_linter/src/rules/jest/valid_expect.rs | 2 +- crates/oxc_linter/src/rules/jsx_a11y/lang.rs | 2 +- .../jsx_a11y/role_supports_aria_props.rs | 2 +- .../rules/nextjs/no_unwanted_polyfillio.rs | 2 +- .../src/rules/oxc/no_accumulating_spread.rs | 4 ++-- .../rules/react/no_direct_mutation_state.rs | 6 ++--- .../src/rules/security/api_keys/mod.rs | 2 +- .../no_side_effects_in_initialization/mod.rs | 2 +- .../typescript/consistent_type_imports.rs | 2 +- crates/oxc_linter/src/utils/react.rs | 6 ++--- crates/oxc_linter/src/utils/unicorn.rs | 2 +- crates/oxc_mangler/src/lib.rs | 2 +- crates/oxc_minifier/README.md | 2 +- .../collapse_variable_declarations.rs | 4 ++-- .../src/ast_passes/exploit_assigns.rs | 4 ++-- .../src/ast_passes/peephole_fold_constants.rs | 6 ++--- .../peephole_minimize_conditions.rs | 4 ++-- .../ast_passes/peephole_remove_dead_code.rs | 4 ++-- .../peephole_replace_known_methods.rs | 4 ++-- .../peephole_substitute_alternate_syntax.rs | 4 ++-- .../src/ast_passes/statement_fusion.rs | 2 +- .../tests/ast_passes/dead_code_elimination.rs | 2 +- .../oxc_module_lexer/tests/integration/esm.rs | 2 +- crates/oxc_parser/src/js/statement.rs | 2 +- crates/oxc_parser/src/lexer/byte_handlers.rs | 2 +- crates/oxc_parser/src/lexer/mod.rs | 6 ++--- crates/oxc_parser/src/lexer/number.rs | 2 +- crates/oxc_prettier/README.md | 2 +- crates/oxc_prettier/src/doc.rs | 4 ++-- .../oxc_prettier/src/format/call_arguments.rs | 2 +- crates/oxc_prettier/src/format/mod.rs | 4 ++-- crates/oxc_prettier/src/lib.rs | 2 +- crates/oxc_prettier/src/needs_parens.rs | 2 +- crates/oxc_prettier/src/options.rs | 4 ++-- crates/oxc_prettier/src/printer/mod.rs | 4 ++-- crates/oxc_sourcemap/src/decode.rs | 4 ++-- crates/oxc_sourcemap/src/encode.rs | 2 +- .../src/common/helper_loader.rs | 6 ++--- .../src/common/module_imports.rs | 2 +- .../src/es2015/arrow_functions.rs | 2 +- .../src/es2016/exponentiation_operator.rs | 4 ++-- .../src/es2017/async_to_generator.rs | 2 +- .../es2018/async_generator_functions/mod.rs | 2 +- .../src/es2018/object_rest_spread.rs | 2 +- .../src/es2019/optional_catch_binding.rs | 2 +- .../src/es2020/nullish_coalescing_operator.rs | 2 +- .../es2021/logical_assignment_operators.rs | 2 +- .../src/es2022/class_properties.rs | 6 ++--- .../src/es2022/class_static_block.rs | 2 +- .../oxc_transformer/src/jsx/display_name.rs | 2 +- crates/oxc_transformer/src/jsx/jsx_impl.rs | 2 +- crates/oxc_transformer/src/jsx/jsx_self.rs | 2 +- crates/oxc_transformer/src/jsx/jsx_source.rs | 2 +- crates/oxc_transformer/src/jsx/refresh.rs | 2 +- crates/oxc_transformer/src/lib.rs | 2 +- .../plugins/inject_global_variables.rs | 2 +- napi/parser/index.d.ts | 2 +- napi/transform/index.d.ts | 2 +- npm/oxc-parser/scripts/generate-packages.mjs | 2 +- .../scripts/generate-packages.mjs | 2 +- npm/oxlint/scripts/generate-packages.mjs | 2 +- tasks/ast_tools/src/generators/visit.rs | 2 +- tasks/common/src/test_file.rs | 2 +- tasks/compat_data/README.md | 2 +- tasks/compat_data/build.js | 4 ++-- tasks/compat_data/chromium-to-electron.js | 2 +- tasks/compat_data/chromium-versions.js | 2 +- tasks/compat_data/es-features.js | 4 ++-- tasks/coverage/misc/fail/oxc-2394.ts | 2 +- tasks/coverage/src/runtime/runtime.js | 2 +- tasks/coverage/src/suite.rs | 2 +- tasks/coverage/src/test262/mod.rs | 2 +- .../src/typescript/transpile_runner.rs | 2 +- tasks/lint_rules/src/eslint-rules.cjs | 24 +++++++++---------- .../fixtures/refresh/react-refresh/README.md | 2 +- 137 files changed, 186 insertions(+), 186 deletions(-) diff --git a/crates/oxc/src/napi/parse.rs b/crates/oxc/src/napi/parse.rs index 6ab5d3ce8e3df8..2406a04b417f0f 100644 --- a/crates/oxc/src/napi/parse.rs +++ b/crates/oxc/src/napi/parse.rs @@ -2,7 +2,7 @@ use napi_derive::napi; /// Babel Parser Options /// -/// <https://github.com/babel/babel/blob/main/packages/babel-parser/typings/babel-parser.d.ts> +/// <https://github.com/babel/babel/blob/v7.26.2/packages/babel-parser/typings/babel-parser.d.ts> #[napi(object)] #[derive(Default)] pub struct ParserOptions { diff --git a/crates/oxc/src/napi/transform.rs b/crates/oxc/src/napi/transform.rs index a4f29d2f985ded..d37ae5db6588ac 100644 --- a/crates/oxc/src/napi/transform.rs +++ b/crates/oxc/src/napi/transform.rs @@ -1,4 +1,4 @@ -// NOTE: Types must be aligned with [@types/babel__core](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/babel__core/index.d.ts). +// NOTE: Types must be aligned with [@types/babel__core](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b5dc32740d9b45d11cff9b025896dd333c795b39/types/babel__core/index.d.ts). #![allow(rustdoc::bare_urls)] @@ -241,7 +241,7 @@ pub struct JsxOptions { /// Enable React Fast Refresh . /// - /// Conforms to the implementation in {@link https://github.com/facebook/react/tree/main/packages/react-refresh} + /// Conforms to the implementation in {@link https://github.com/facebook/react/tree/v18.3.1/packages/react-refresh} /// /// @default false pub refresh: Option<Either<bool, ReactRefreshOptions>>, diff --git a/crates/oxc_allocator/src/boxed.rs b/crates/oxc_allocator/src/boxed.rs index 209e6011d76126..3271631cb1c121 100644 --- a/crates/oxc_allocator/src/boxed.rs +++ b/crates/oxc_allocator/src/boxed.rs @@ -1,6 +1,6 @@ //! Arena Box. //! -//! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) +//! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/24004745a8ed4939fc0dc7332bfd1268ac52285f/crates/ast/src/arena.rs) use std::{ self, diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 273120f69e66cc..471e47e47fc1c3 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -1,6 +1,6 @@ //! Arena Vec. //! -//! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/ast/src/arena.rs) +//! Originally based on [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/24004745a8ed4939fc0dc7332bfd1268ac52285f/crates/ast/src/arena.rs) use std::{ self, diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 06107e41dd75eb..4d6d7bf766f8ee 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -2414,7 +2414,7 @@ pub enum ExportDefaultDeclarationKind<'a> { /// Supports: /// * `import {"\0 any unicode" as foo} from ""` /// * `export {foo as "\0 any unicode"}` -/// * es2022: <https://github.com/estree/estree/blob/master/es2022.md#modules> +/// * es2022: <https://github.com/estree/estree/blob/e6015c4c63118634749001b1cd1c3f7a0388f16e/es2022.md#modules> /// * <https://github.com/tc39/ecma262/pull/2154> #[ast(visit)] #[derive(Debug, Clone)] diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index e96b3ad41996a4..81033cd8a49878 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1,6 +1,6 @@ //! TypeScript Definitions //! -//! - [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/ast-spec) +//! - [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/v8.9.0/packages/ast-spec) //! - [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md) #![allow(missing_docs)] // FIXME diff --git a/crates/oxc_ast/src/ast_impl/ts.rs b/crates/oxc_ast/src/ast_impl/ts.rs index 4eff1693778d44..019a5d32cfa05b 100644 --- a/crates/oxc_ast/src/ast_impl/ts.rs +++ b/crates/oxc_ast/src/ast_impl/ts.rs @@ -1,6 +1,6 @@ //! TypeScript Definitions //! -//! [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/ast-spec) +//! [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/v8.9.0/packages/ast-spec) //! [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md) #![warn(missing_docs)] diff --git a/crates/oxc_ast/src/generated/visit.rs b/crates/oxc_ast/src/generated/visit.rs index 06d8fbcf2d0c64..a528d712d37378 100644 --- a/crates/oxc_ast/src/generated/visit.rs +++ b/crates/oxc_ast/src/generated/visit.rs @@ -5,7 +5,7 @@ //! //! See: //! * [visitor pattern](https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html) -//! * [rustc visitor](https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast/src/visit.rs) +//! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs) # -//! * [rustc visitor](https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast/src/visit.rs) +//! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs) #![allow( unused_variables, diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index 4968f7a40a3839..55532ec05f99f6 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -34,7 +34,7 @@ //! [`oxc_parser`]: <https://docs.rs/oxc_parser> //! [`Parser`]: <https://docs.rs/oxc_parser/latest/oxc_parser/struct.Parser.html> //! [estree]: <https://github.com/estree/estree> -//! [typescript-eslint]: <https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/ast-spec> +//! [typescript-eslint]: <https://github.com/typescript-eslint/typescript-eslint/tree/v8.9.0/packages/ast-spec> //! [ECMAScript spec]: <https://tc39.es/ecma262/> //! [tsc]: <https://github.com/microsoft/TypeScript> //! [`Traverse`]: <https://github.com/oxc-project/oxc/tree/main/crates/oxc_traverse> diff --git a/crates/oxc_codegen/src/comment.rs b/crates/oxc_codegen/src/comment.rs index 3365b2c11ecb96..cda260537f8e6f 100644 --- a/crates/oxc_codegen/src/comment.rs +++ b/crates/oxc_codegen/src/comment.rs @@ -39,7 +39,7 @@ impl<'a> Codegen<'a> { /// `#__PURE__` Notation Specification /// - /// <https://github.com/javascript-compiler-hints/compiler-notations-spec/blob/main/pure-notation-spec.md> + /// <https://github.com/javascript-compiler-hints/compiler-notations-spec/blob/c14f7e197cb225c9eee877143536665ce3150712/pure-notation-spec.md> fn is_annotation_comment(&self, comment: &Comment) -> bool { let s = comment.content_span().source_text(self.source_text).trim_start(); if let Some(s) = s.strip_prefix(['@', '#']) { diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 06b29c25748bcd..a7f1cc4d9b8d72 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -67,7 +67,7 @@ impl<'a> Gen for Directive<'a> { p.print_indent(); // A Use Strict Directive may not contain an EscapeSequence or LineContinuation. // So here should print original `directive` value, the `expression` value is escaped str. - // See https://github.com/babel/babel/blob/main/packages/babel-generator/src/generators/base.ts#L64 + // See https://github.com/babel/babel/blob/v7.26.2/packages/babel-generator/src/generators/base.ts#L64 p.wrap_quote(|p, _| { p.print_str(self.directive.as_str()); }); diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index b55933a8de0d7e..28f5c684799a9d 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -1,7 +1,7 @@ //! Oxc Codegen //! //! Code adapted from -//! * [esbuild](https://github.com/evanw/esbuild/blob/main/internal/js_printer/js_printer.go) +//! * [esbuild](https://github.com/evanw/esbuild/blob/v0.24.0/internal/js_printer/js_printer.go) #![warn(missing_docs)] mod binary_expr_visitor; diff --git a/crates/oxc_codegen/tests/integration/esbuild.rs b/crates/oxc_codegen/tests/integration/esbuild.rs index 690afb13d8ae32..7dc42d806eceac 100644 --- a/crates/oxc_codegen/tests/integration/esbuild.rs +++ b/crates/oxc_codegen/tests/integration/esbuild.rs @@ -1,6 +1,6 @@ //! Tests ported from `esbuild` -//! * <https://github.com/evanw/esbuild/blob/main/internal/js_printer/js_printer_test.go> -//! * <https://github.com/evanw/esbuild/blob/main/internal/js_parser/js_parser_test.go> +//! * <https://github.com/evanw/esbuild/blob/v0.24.0/internal/js_printer/js_printer_test.go> +//! * <https://github.com/evanw/esbuild/blob/v0.24.0/internal/js_parser/js_parser_test.go> use crate::tester::{test, test_minify}; diff --git a/crates/oxc_codegen/tests/integration/pure_comments.rs b/crates/oxc_codegen/tests/integration/pure_comments.rs index 5ceb65abec09c3..8457d650ed80b4 100644 --- a/crates/oxc_codegen/tests/integration/pure_comments.rs +++ b/crates/oxc_codegen/tests/integration/pure_comments.rs @@ -133,7 +133,7 @@ const defineSSRCustomElement = () => { const Component = // #__PURE__ React.forwardRef((props, ref) => {}); ", - // Copy from <https://github.com/rolldown-rs/rolldown/blob/main/crates/rolldown/tests/esbuild/dce/remove_unused_pure_comment_calls/entry.js> + // Copy from <https://github.com/rolldown-rs/rolldown/blob/v0.14.0/crates/rolldown/tests/esbuild/dce/remove_unused_pure_comment_calls/entry.js> " function bar() {} let bare = foo(bar); diff --git a/crates/oxc_codegen/tests/integration/unit.rs b/crates/oxc_codegen/tests/integration/unit.rs index d104e8989bd2c3..2dc4bd1e7cd9d1 100644 --- a/crates/oxc_codegen/tests/integration/unit.rs +++ b/crates/oxc_codegen/tests/integration/unit.rs @@ -59,7 +59,7 @@ fn shorthand() { test("let { x } = y", "let { x } = y;\n"); test("({ x: (x) })", "({ x });\n"); test("({ x } = y)", "({x} = y);\n"); - // https://github.com/tc39/test262/blob/main/test/language/expressions/object/__proto__-permitted-dup-shorthand.js + // https://github.com/tc39/test262/blob/05c45a4c430ab6fee3e0c7f0d47d8a30d8876a6d/test/language/expressions/object/__proto__-permitted-dup-shorthand.js test("var obj = { __proto__, __proto__, };", "var obj = {\n\t__proto__,\n\t__proto__\n};\n"); test("var obj = { __proto__: __proto__, };", "var obj = { __proto__: __proto__ };\n"); } diff --git a/crates/oxc_diagnostics/src/reporter/json.rs b/crates/oxc_diagnostics/src/reporter/json.rs index 2a52fe9767736f..c31b9ea383778d 100644 --- a/crates/oxc_diagnostics/src/reporter/json.rs +++ b/crates/oxc_diagnostics/src/reporter/json.rs @@ -27,7 +27,7 @@ impl DiagnosticReporter for JsonReporter { } } -/// <https://github.com/fregante/eslint-formatters/tree/main/packages/eslint-formatter-json> +/// <https://github.com/fregante/eslint-formatters/tree/ae1fd9748596447d1fd09625c33d9e7ba9a3d06d/packages/eslint-formatter-json> #[allow(clippy::print_stdout)] fn format_json(diagnostics: &mut Vec<Error>) { let handler = JSONReportHandler::new(); diff --git a/crates/oxc_diagnostics/src/reporter/unix.rs b/crates/oxc_diagnostics/src/reporter/unix.rs index e91bf5f2c4d963..a3e9ecaa2297ba 100644 --- a/crates/oxc_diagnostics/src/reporter/unix.rs +++ b/crates/oxc_diagnostics/src/reporter/unix.rs @@ -37,7 +37,7 @@ impl DiagnosticReporter for UnixReporter { } } -/// <https://github.com/fregante/eslint-formatters/tree/main/packages/eslint-formatter-unix> +/// <https://github.com/fregante/eslint-formatters/tree/ae1fd9748596447d1fd09625c33d9e7ba9a3d06d/packages/eslint-formatter-unix> fn format_unix(diagnostic: &Error) -> String { let Info { line, column, filename, message, severity, rule_id } = Info::new(diagnostic); let severity = match severity { diff --git a/crates/oxc_isolated_declarations/src/lib.rs b/crates/oxc_isolated_declarations/src/lib.rs index 2a834c0e5f267e..18c7e5ec369a9a 100644 --- a/crates/oxc_isolated_declarations/src/lib.rs +++ b/crates/oxc_isolated_declarations/src/lib.rs @@ -3,7 +3,7 @@ //! References: //! * <https://devblogs.microsoft.com/typescript/announcing-typescript-5-5-rc/#isolated-declarations> //! * <https://www.typescriptlang.org/tsconfig#isolatedDeclarations> -//! * <https://github.com/microsoft/TypeScript/blob/main/src/compiler/transformers/declarations.ts> +//! * <https://github.com/microsoft/TypeScript/blob/v5.6.3/src/compiler/transformers/declarations.ts> mod class; mod declaration; diff --git a/crates/oxc_isolated_declarations/tests/deno/mod.rs b/crates/oxc_isolated_declarations/tests/deno/mod.rs index b320b6738032cc..992fe918620c5f 100644 --- a/crates/oxc_isolated_declarations/tests/deno/mod.rs +++ b/crates/oxc_isolated_declarations/tests/deno/mod.rs @@ -1,4 +1,4 @@ -//! Copy from <https://github.com/denoland/deno_graph/blob/main/src/fast_check/transform_dts.rs#L932-#L1532> +//! Copy from <https://github.com/denoland/deno_graph/blob/0.84.0/src/fast_check/transform_dts.rs#L932-#L1532> //! Make some changes to conform to the Isolated Declarations output #[cfg(test)] diff --git a/crates/oxc_linter/src/config/settings/jsdoc.rs b/crates/oxc_linter/src/config/settings/jsdoc.rs index 3f8fe24d6e62ab..f8e3079935edc0 100644 --- a/crates/oxc_linter/src/config/settings/jsdoc.rs +++ b/crates/oxc_linter/src/config/settings/jsdoc.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::utils::default_true; -// <https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/settings.md> +// <https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.5.0/docs/settings.md> #[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)] #[cfg_attr(test, derive(PartialEq))] pub struct JSDocPluginSettings { @@ -123,7 +123,7 @@ impl JSDocPluginSettings { Some(Cow::Borrowed(message)) } _ => { - // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/settings.md#default-preferred-aliases + // https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.5.0/docs/settings.md#default-preferred-aliases let aliased_name = match original_name { "virtual" => "abstract", "extends" => "augments", diff --git a/crates/oxc_linter/src/fixer/fix.rs b/crates/oxc_linter/src/fixer/fix.rs index d2375ae65c4c9f..aeec3ce372cdc1 100644 --- a/crates/oxc_linter/src/fixer/fix.rs +++ b/crates/oxc_linter/src/fixer/fix.rs @@ -457,7 +457,7 @@ impl<'a> CompositeFix<'a> { // } /// Gets one fix from the fixes. If we retrieve multiple fixes, this merges those into one. - /// <https://github.com/eslint/eslint/blob/main/lib/linter/report-translator.js#L181-L203> + /// <https://github.com/eslint/eslint/blob/v9.9.1/lib/linter/report-translator.js#L181-L203> pub fn normalize_fixes(self, source_text: &str) -> Fix<'a> { match self { CompositeFix::Single(fix) => fix, @@ -472,7 +472,7 @@ impl<'a> CompositeFix<'a> { /// 2. contains overlapped ranges /// 3. contains negative ranges (span.start > span.end) /// - /// <https://github.com/eslint/eslint/blob/main/lib/linter/report-translator.js#L147-L179> + /// <https://github.com/eslint/eslint/blob/v9.9.1/lib/linter/report-translator.js#L147-L179> fn merge_fixes(fixes: Vec<Fix<'a>>, source_text: &str) -> Fix<'a> { let mut fixes = fixes; if fixes.is_empty() { diff --git a/crates/oxc_linter/src/fixer/mod.rs b/crates/oxc_linter/src/fixer/mod.rs index 0083f4d7100b38..8b8b0f212c4420 100644 --- a/crates/oxc_linter/src/fixer/mod.rs +++ b/crates/oxc_linter/src/fixer/mod.rs @@ -11,7 +11,7 @@ use crate::LintContext; /// Produces [`RuleFix`] instances. Inspired by ESLint's [`RuleFixer`]. /// -/// [`RuleFixer`]: https://github.com/eslint/eslint/blob/main/lib/linter/rule-fixer.js +/// [`RuleFixer`]: https://github.com/eslint/eslint/blob/v9.9.1/lib/linter/rule-fixer.js #[derive(Clone, Copy)] #[must_use] pub struct RuleFixer<'c, 'a: 'c> { @@ -671,7 +671,7 @@ mod test { } // Remain test caces picked from eslint - // <https://github.com/eslint/eslint/blob/main/tests/lib/linter/report-translator.js> + // <https://github.com/eslint/eslint/blob/v9.9.1/tests/lib/linter/report-translator.js> // 1. Combining autofixes #[test] fn merge_fixes_into_one() { diff --git a/crates/oxc_linter/src/globals.rs b/crates/oxc_linter/src/globals.rs index 2b0ed497679262..ad642e1f518b3f 100644 --- a/crates/oxc_linter/src/globals.rs +++ b/crates/oxc_linter/src/globals.rs @@ -70,7 +70,7 @@ pub const VALID_ARIA_PROPS: phf::Set<&'static str> = phf_set! { /// set of valid ARIA role definitions /// Reference: <https://www.w3.org/TR/wai-aria/#role_definitions> -/// Reference: <https://github.com/A11yance/aria-query/blob/main/src/rolesMap.js> +/// Reference: <https://github.com/A11yance/aria-query/blob/v5.3.2/src/rolesMap.js> pub const VALID_ARIA_ROLES: phf::Set<&'static str> = phf_set! { "alert", "alertdialog", @@ -355,7 +355,7 @@ pub const HTML_TAG: phf::Set<&'static str> = phf_set! { /// if it's not reserved, then it can have aria-* roles, states, and properties /// Reference: <https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_12> /// Reference: <https://www.w3.org/TR/html-aria/#rules-wd> -/// Reference: <https://github.com/A11yance/aria-query/blob/main/src/domMap.js> +/// Reference: <https://github.com/A11yance/aria-query/blob/v5.3.2/src/domMap.js> pub const RESERVED_HTML_TAG: phf::Set<&'static str> = phf_set! { "base", "col", diff --git a/crates/oxc_linter/src/rules/eslint/array_callback_return/mod.rs b/crates/oxc_linter/src/rules/eslint/array_callback_return/mod.rs index 5c78c3b462b3bf..ecadb97f30496e 100644 --- a/crates/oxc_linter/src/rules/eslint/array_callback_return/mod.rs +++ b/crates/oxc_linter/src/rules/eslint/array_callback_return/mod.rs @@ -132,7 +132,7 @@ impl Rule for ArrayCallbackReturn { } } -/// Code ported from [eslint](https://github.com/eslint/eslint/blob/main/lib/rules/array-callback-return.js) +/// Code ported from [eslint](https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/array-callback-return.js) /// We're currently on a `Function` or `ArrowFunctionExpression`, findout if it is an argument /// to the target array methods we're interested in. pub fn get_array_method_name<'a>( diff --git a/crates/oxc_linter/src/rules/eslint/no_control_regex.rs b/crates/oxc_linter/src/rules/eslint/no_control_regex.rs index d0b4d31590bdfd..e5865dd34a8695 100644 --- a/crates/oxc_linter/src/rules/eslint/no_control_regex.rs +++ b/crates/oxc_linter/src/rules/eslint/no_control_regex.rs @@ -297,7 +297,7 @@ mod tests { #[test] fn test() { // test cases taken from eslint. See: - // https://github.com/eslint/eslint/blob/main/tests/lib/rules/no-control-regex.js + // https://github.com/eslint/eslint/blob/v9.9.1/tests/lib/rules/no-control-regex.js Tester::new( NoControlRegex::NAME, vec![ diff --git a/crates/oxc_linter/src/rules/eslint/no_empty_character_class.rs b/crates/oxc_linter/src/rules/eslint/no_empty_character_class.rs index 588a98876ef667..2a2c9189a085e8 100644 --- a/crates/oxc_linter/src/rules/eslint/no_empty_character_class.rs +++ b/crates/oxc_linter/src/rules/eslint/no_empty_character_class.rs @@ -1,5 +1,5 @@ use memchr::memchr2; -// Ported from https://github.com/eslint/eslint/blob/main/lib/rules/no-empty-character-class.js +// Ported from https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/no-empty-character-class.js use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; diff --git a/crates/oxc_linter/src/rules/eslint/no_eval.rs b/crates/oxc_linter/src/rules/eslint/no_eval.rs index dbe81ab82ee428..19ff16e0e524d4 100644 --- a/crates/oxc_linter/src/rules/eslint/no_eval.rs +++ b/crates/oxc_linter/src/rules/eslint/no_eval.rs @@ -1,4 +1,4 @@ -// Ported from https://github.com/eslint/eslint/tree/main/lib/rules/no-eval.js +// Ported from https://github.com/eslint/eslint/tree/v9.9.1/lib/rules/no-eval.js use oxc_ast::{ast::Expression, AstKind}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; diff --git a/crates/oxc_linter/src/rules/eslint/no_obj_calls.rs b/crates/oxc_linter/src/rules/eslint/no_obj_calls.rs index e6b6284edf58b2..2cc40c21df531b 100644 --- a/crates/oxc_linter/src/rules/eslint/no_obj_calls.rs +++ b/crates/oxc_linter/src/rules/eslint/no_obj_calls.rs @@ -164,7 +164,7 @@ impl Rule for NoObjCalls { #[test] fn test() { use crate::tester::Tester; - // see: https://github.com/eslint/eslint/blob/main/tests/lib/rules/no-obj-calls.js + // see: https://github.com/eslint/eslint/blob/v9.9.1/tests/lib/rules/no-obj-calls.js let pass = vec![ ("const m = Math;", None), diff --git a/crates/oxc_linter/src/rules/eslint/no_useless_escape.rs b/crates/oxc_linter/src/rules/eslint/no_useless_escape.rs index bdfe638b015e41..befea169ab60fd 100644 --- a/crates/oxc_linter/src/rules/eslint/no_useless_escape.rs +++ b/crates/oxc_linter/src/rules/eslint/no_useless_escape.rs @@ -179,7 +179,7 @@ fn check_character( * it only needs to be escaped in character classes if it's at the beginning of the character class. To * account for this, consider it to be a valid escape character outside of character classes, and filter * out '^' characters that appear at the start of a character class. - * (From ESLint source: https://github.com/eslint/eslint/blob/main/lib/rules/no-useless-escape.js) + * (From ESLint source: https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/no-useless-escape.js) */ if class.span.start + 1 == span.start { return None; @@ -216,7 +216,7 @@ fn check_character( * class, and is not at either edge of the character class. To account for this, don't consider '-' * characters to be valid in general, and filter out '-' characters that appear in the middle of a * character class. - * (From ESLint source: https://github.com/eslint/eslint/blob/main/lib/rules/no-useless-escape.js) + * (From ESLint source: https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/no-useless-escape.js) */ if class.span.start + 1 != span.start && span.end != class.span.end - 1 { return None; diff --git a/crates/oxc_linter/src/rules/eslint/no_var.rs b/crates/oxc_linter/src/rules/eslint/no_var.rs index 7f7bee97322e7f..a30e6d49373f19 100644 --- a/crates/oxc_linter/src/rules/eslint/no_var.rs +++ b/crates/oxc_linter/src/rules/eslint/no_var.rs @@ -17,9 +17,9 @@ fn no_var_diagnostic(span: Span) -> OxcDiagnostic { #[derive(Debug, Default, Clone)] pub struct NoVar; -// doc: https://github.com/eslint/eslint/blob/main/docs/src/rules/no-var.md -// code: https://github.com/eslint/eslint/blob/main/lib/rules/no-var.js -// test: https://github.com/eslint/eslint/blob/main/tests/lib/rules/no-var.js +// doc: https://github.com/eslint/eslint/blob/v9.9.1/docs/src/rules/no-var.md +// code: https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/no-var.js +// test: https://github.com/eslint/eslint/blob/v9.9.1/tests/lib/rules/no-var.js declare_oxc_lint!( /// ### What it does diff --git a/crates/oxc_linter/src/rules/eslint/radix.rs b/crates/oxc_linter/src/rules/eslint/radix.rs index 383c62ef2a18f3..d22e3e76c55c6d 100644 --- a/crates/oxc_linter/src/rules/eslint/radix.rs +++ b/crates/oxc_linter/src/rules/eslint/radix.rs @@ -31,9 +31,9 @@ pub struct Radix { radix_type: RadixType, } -// doc: https://github.com/eslint/eslint/blob/main/docs/src/rules/radix.md -// code: https://github.com/eslint/eslint/blob/main/lib/rules/radix.js -// test: https://github.com/eslint/eslint/blob/main/tests/lib/rules/radix.js +// doc: https://github.com/eslint/eslint/blob/v9.9.1/docs/src/rules/radix.md +// code: https://github.com/eslint/eslint/blob/v9.9.1/lib/rules/radix.js +// test: https://github.com/eslint/eslint/blob/v9.9.1/tests/lib/rules/radix.js declare_oxc_lint!( /// ### What it does diff --git a/crates/oxc_linter/src/rules/import/default.rs b/crates/oxc_linter/src/rules/import/default.rs index e15a84d877a354..0344138a4d4595 100644 --- a/crates/oxc_linter/src/rules/import/default.rs +++ b/crates/oxc_linter/src/rules/import/default.rs @@ -11,7 +11,7 @@ fn default_diagnostic(imported_name: &str, span: Span) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/default.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/default.md> #[derive(Debug, Default, Clone)] pub struct Default; diff --git a/crates/oxc_linter/src/rules/import/export.rs b/crates/oxc_linter/src/rules/import/export.rs index db1edca4151425..cb79d91b35611a 100644 --- a/crates/oxc_linter/src/rules/import/export.rs +++ b/crates/oxc_linter/src/rules/import/export.rs @@ -13,7 +13,7 @@ fn no_named_export(module_name: &str, span: Span) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/export.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/export.md> #[derive(Debug, Default, Clone)] pub struct Export; diff --git a/crates/oxc_linter/src/rules/import/first.rs b/crates/oxc_linter/src/rules/import/first.rs index 32c60e16078b2b..57ff1d6329a6d3 100644 --- a/crates/oxc_linter/src/rules/import/first.rs +++ b/crates/oxc_linter/src/rules/import/first.rs @@ -95,7 +95,7 @@ fn is_relative_path(path: &str) -> bool { path.starts_with("./") } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/first.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/first.md> impl Rule for First { fn from_configuration(value: serde_json::Value) -> Self { let obj = value.get(0); diff --git a/crates/oxc_linter/src/rules/import/import_no_namespace.rs b/crates/oxc_linter/src/rules/import/import_no_namespace.rs index 44371dc8253689..09ede4e7b88de8 100644 --- a/crates/oxc_linter/src/rules/import/import_no_namespace.rs +++ b/crates/oxc_linter/src/rules/import/import_no_namespace.rs @@ -82,7 +82,7 @@ declare_oxc_lint!( pending // TODO: fixer ); -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-namespace.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-namespace.md> impl Rule for ImportNoNamespace { fn from_configuration(value: serde_json::Value) -> Self { let obj = value.get(0); diff --git a/crates/oxc_linter/src/rules/import/max_dependencies.rs b/crates/oxc_linter/src/rules/import/max_dependencies.rs index 44464735f05e0c..17bf68e302df8d 100644 --- a/crates/oxc_linter/src/rules/import/max_dependencies.rs +++ b/crates/oxc_linter/src/rules/import/max_dependencies.rs @@ -16,7 +16,7 @@ fn max_dependencies_diagnostic<S: Into<Cow<'static, str>>>( .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/max-dependencies.md> #[derive(Debug, Default, Clone)] pub struct MaxDependencies(Box<MaxDependenciesConfig>); diff --git a/crates/oxc_linter/src/rules/import/named.rs b/crates/oxc_linter/src/rules/import/named.rs index a1988ab3f88e50..6718339147f73f 100644 --- a/crates/oxc_linter/src/rules/import/named.rs +++ b/crates/oxc_linter/src/rules/import/named.rs @@ -11,7 +11,7 @@ fn named_diagnostic(imported_name: &str, module_name: &str, span: Span) -> OxcDi .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/named.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/named.md> #[derive(Debug, Default, Clone)] pub struct Named; diff --git a/crates/oxc_linter/src/rules/import/namespace.rs b/crates/oxc_linter/src/rules/import/namespace.rs index 8173e6886375f6..33a7a58e201e30 100644 --- a/crates/oxc_linter/src/rules/import/namespace.rs +++ b/crates/oxc_linter/src/rules/import/namespace.rs @@ -42,7 +42,7 @@ fn assignment(span: Span, namespace_name: &str) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/namespace.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/namespace.md> #[derive(Debug, Default, Clone)] pub struct Namespace { allow_computed: bool, diff --git a/crates/oxc_linter/src/rules/import/no_amd.rs b/crates/oxc_linter/src/rules/import/no_amd.rs index 1a5261c289eb4c..e62fed296f2bdd 100644 --- a/crates/oxc_linter/src/rules/import/no_amd.rs +++ b/crates/oxc_linter/src/rules/import/no_amd.rs @@ -47,7 +47,7 @@ declare_oxc_lint!( restriction ); -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-amd.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-amd.md> impl Rule for NoAmd { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { // not in top level diff --git a/crates/oxc_linter/src/rules/import/no_commonjs.rs b/crates/oxc_linter/src/rules/import/no_commonjs.rs index 6411f5784dac13..0dc3151028d402 100644 --- a/crates/oxc_linter/src/rules/import/no_commonjs.rs +++ b/crates/oxc_linter/src/rules/import/no_commonjs.rs @@ -128,7 +128,7 @@ fn is_conditional(parent_node: &AstNode, ctx: &LintContext) -> bool { is_conditional(parent, ctx) } } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-commonjs.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-commonjs.md> impl Rule for NoCommonjs { fn from_configuration(value: serde_json::Value) -> Self { let obj = value.get(0); diff --git a/crates/oxc_linter/src/rules/import/no_cycle.rs b/crates/oxc_linter/src/rules/import/no_cycle.rs index 0487ee062736b2..8e62f28e29dcae 100644 --- a/crates/oxc_linter/src/rules/import/no_cycle.rs +++ b/crates/oxc_linter/src/rules/import/no_cycle.rs @@ -18,7 +18,7 @@ fn no_cycle_diagnostic(span: Span, paths: &str) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-cycle.md> #[derive(Debug, Clone)] pub struct NoCycle { /// maximum dependency depth to traverse diff --git a/crates/oxc_linter/src/rules/import/no_deprecated.rs b/crates/oxc_linter/src/rules/import/no_deprecated.rs index ee4020527c41f4..b4d2c766e02381 100644 --- a/crates/oxc_linter/src/rules/import/no_deprecated.rs +++ b/crates/oxc_linter/src/rules/import/no_deprecated.rs @@ -12,7 +12,7 @@ use crate::{ // #[diagnostic(severity(warning), help(""))] // struct NoDeprecatedDiagnostic(CompactStr, #[label] pub Span); -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-deprecated.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-deprecated.md> #[derive(Debug, Default, Clone)] pub struct NoDeprecated; diff --git a/crates/oxc_linter/src/rules/import/no_duplicates.rs b/crates/oxc_linter/src/rules/import/no_duplicates.rs index d35ee702b9d1e4..5b37aa0db2cbad 100644 --- a/crates/oxc_linter/src/rules/import/no_duplicates.rs +++ b/crates/oxc_linter/src/rules/import/no_duplicates.rs @@ -32,7 +32,7 @@ where .with_help("Merge these imports into a single import statement") } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-duplicates.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-duplicates.md> #[derive(Debug, Default, Clone)] pub struct NoDuplicates { prefer_inline: bool, diff --git a/crates/oxc_linter/src/rules/import/no_named_as_default.rs b/crates/oxc_linter/src/rules/import/no_named_as_default.rs index a6e352057775ba..5518e032d45113 100644 --- a/crates/oxc_linter/src/rules/import/no_named_as_default.rs +++ b/crates/oxc_linter/src/rules/import/no_named_as_default.rs @@ -15,7 +15,7 @@ fn no_named_as_default_diagnostic( .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-named-as-default-member.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default-member.md> #[derive(Debug, Default, Clone)] pub struct NoNamedAsDefault; diff --git a/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs b/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs index b34349de518c52..65e5b2ece28d5a 100644 --- a/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs +++ b/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs @@ -22,7 +22,7 @@ fn no_named_as_default_member_dignostic( .with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-named-as-default-member.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-named-as-default-member.md> #[derive(Debug, Default, Clone)] pub struct NoNamedAsDefaultMember; diff --git a/crates/oxc_linter/src/rules/import/no_unused_modules.rs b/crates/oxc_linter/src/rules/import/no_unused_modules.rs index 8a4dd3f19a5a59..f1880a755235ba 100644 --- a/crates/oxc_linter/src/rules/import/no_unused_modules.rs +++ b/crates/oxc_linter/src/rules/import/no_unused_modules.rs @@ -10,7 +10,7 @@ fn no_exports_found(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("No exports found").with_label(span) } -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unused-modules.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-unused-modules.md> #[derive(Debug, Default, Clone)] pub struct NoUnusedModules { missing_exports: bool, diff --git a/crates/oxc_linter/src/rules/import/unambiguous.rs b/crates/oxc_linter/src/rules/import/unambiguous.rs index 810fb9b023802b..248c3e87272880 100644 --- a/crates/oxc_linter/src/rules/import/unambiguous.rs +++ b/crates/oxc_linter/src/rules/import/unambiguous.rs @@ -45,7 +45,7 @@ declare_oxc_lint!( restriction ); -/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/unambiguous.md> +/// <https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/unambiguous.md> impl Rule for Unambiguous { fn run_once(&self, ctx: &LintContext<'_>) { if ctx.semantic().module_record().not_esm { diff --git a/crates/oxc_linter/src/rules/jest/consistent_test_it.rs b/crates/oxc_linter/src/rules/jest/consistent_test_it.rs index 2c5bfe0ad1290e..657e245c701125 100644 --- a/crates/oxc_linter/src/rules/jest/consistent_test_it.rs +++ b/crates/oxc_linter/src/rules/jest/consistent_test_it.rs @@ -158,7 +158,7 @@ declare_oxc_lint!( /// Decides whether to use `test` or `it` within a `describe` scope. /// /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/consistent-test-it.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/expect_expect.rs b/crates/oxc_linter/src/rules/jest/expect_expect.rs index 9251d001c07eb9..c95e72c1fffd79 100644 --- a/crates/oxc_linter/src/rules/jest/expect_expect.rs +++ b/crates/oxc_linter/src/rules/jest/expect_expect.rs @@ -68,7 +68,7 @@ declare_oxc_lint!( /// test('should assert something', () => {}); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/expect-expect.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_alias_methods.rs b/crates/oxc_linter/src/rules/jest/no_alias_methods.rs index 291492107c82ac..5a53652955cda3 100644 --- a/crates/oxc_linter/src/rules/jest/no_alias_methods.rs +++ b/crates/oxc_linter/src/rules/jest/no_alias_methods.rs @@ -43,7 +43,7 @@ declare_oxc_lint!( /// expect(a).toThrowError(); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-alias-methods.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-alias-methods.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_commented_out_tests.rs b/crates/oxc_linter/src/rules/jest/no_commented_out_tests.rs index 85a61bae6f6bef..05f8115e42853f 100644 --- a/crates/oxc_linter/src/rules/jest/no_commented_out_tests.rs +++ b/crates/oxc_linter/src/rules/jest/no_commented_out_tests.rs @@ -38,7 +38,7 @@ declare_oxc_lint!( /// // test.skip('foo', () => {}); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-commented-out-tests.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-commented-out-tests.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs b/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs index 0ef65084e2d823..27c08a317154a9 100644 --- a/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs +++ b/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs @@ -51,7 +51,7 @@ declare_oxc_lint!( /// }); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-conditional-expect.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json 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 6b5b667991acb4..f0275a7289631e 100644 --- a/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs +++ b/crates/oxc_linter/src/rules/jest/no_disabled_tests.rs @@ -49,7 +49,7 @@ declare_oxc_lint!( /// }); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-disabled-tests.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_focused_tests.rs b/crates/oxc_linter/src/rules/jest/no_focused_tests.rs index f598b879bd0b86..317254c0b0db3f 100644 --- a/crates/oxc_linter/src/rules/jest/no_focused_tests.rs +++ b/crates/oxc_linter/src/rules/jest/no_focused_tests.rs @@ -50,7 +50,7 @@ declare_oxc_lint!( /// `(); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-focused-tests.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_identical_title.rs b/crates/oxc_linter/src/rules/jest/no_identical_title.rs index 5a91f89d4d5c2b..251b55c6cf38d0 100644 --- a/crates/oxc_linter/src/rules/jest/no_identical_title.rs +++ b/crates/oxc_linter/src/rules/jest/no_identical_title.rs @@ -56,7 +56,7 @@ declare_oxc_lint!( /// }); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-identical-title.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/no_jasmine_globals.rs b/crates/oxc_linter/src/rules/jest/no_jasmine_globals.rs index 28948fab702d3c..fc7b126e0b1cd8 100644 --- a/crates/oxc_linter/src/rules/jest/no_jasmine_globals.rs +++ b/crates/oxc_linter/src/rules/jest/no_jasmine_globals.rs @@ -14,7 +14,7 @@ fn no_jasmine_globals_diagnostic(x0: &str, x1: &str, span2: Span) -> OxcDiagnost OxcDiagnostic::warn(format!("{x0:?}")).with_help(format!("{x1:?}")).with_label(span2) } -/// <https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-jasmine-globals.md> +/// <https://github.com/jest-community/eslint-plugin-jest/blob/v28.9.0/docs/rules/no-jasmine-globals.md> #[derive(Debug, Default, Clone)] pub struct NoJasmineGlobals; diff --git a/crates/oxc_linter/src/rules/jest/no_mocks_import.rs b/crates/oxc_linter/src/rules/jest/no_mocks_import.rs index 6fc5d1fda8d7cf..6b11fd34ff0383 100644 --- a/crates/oxc_linter/src/rules/jest/no_mocks_import.rs +++ b/crates/oxc_linter/src/rules/jest/no_mocks_import.rs @@ -13,7 +13,7 @@ fn no_mocks_import_diagnostic(span: Span) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-mocks-import.md> +/// <https://github.com/jest-community/eslint-plugin-jest/blob/v28.9.0/docs/rules/no-mocks-import.md> #[derive(Debug, Default, Clone)] pub struct NoMocksImport; diff --git a/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs b/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs index b9eebaf72a7208..04b92f236ff6b0 100644 --- a/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs +++ b/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs @@ -22,7 +22,7 @@ fn no_standalone_expect_diagnostic(span: Span) -> OxcDiagnostic { .with_label(span) } -/// <https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-standalone-expect.md> +/// <https://github.com/jest-community/eslint-plugin-jest/blob/v28.9.0/docs/rules/no-standalone-expect.md> #[derive(Debug, Default, Clone)] pub struct NoStandaloneExpect(Box<NoStandaloneExpectConfig>); diff --git a/crates/oxc_linter/src/rules/jest/no_test_prefixes.rs b/crates/oxc_linter/src/rules/jest/no_test_prefixes.rs index 636b02c57ec48c..d76bc9902093f4 100644 --- a/crates/oxc_linter/src/rules/jest/no_test_prefixes.rs +++ b/crates/oxc_linter/src/rules/jest/no_test_prefixes.rs @@ -42,7 +42,7 @@ declare_oxc_lint!( /// xdescribe('foo'); // invalid /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-test-prefixes.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/no-test-prefixes.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/prefer_hooks_in_order.rs b/crates/oxc_linter/src/rules/jest/prefer_hooks_in_order.rs index e16941dc0e6ee3..ff532302a3c89d 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_hooks_in_order.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_hooks_in_order.rs @@ -128,7 +128,7 @@ declare_oxc_lint!( /// ``` /// /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/prefer-hooks-in-order.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs b/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs index 86fb024d1ab404..4914a0318d4393 100644 --- a/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs +++ b/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs @@ -58,7 +58,7 @@ declare_oxc_lint!( /// })); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/valid-describe-callback.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jest/valid_expect.rs b/crates/oxc_linter/src/rules/jest/valid_expect.rs index 938fdf3840d665..7f63d91ea00abc 100644 --- a/crates/oxc_linter/src/rules/jest/valid_expect.rs +++ b/crates/oxc_linter/src/rules/jest/valid_expect.rs @@ -68,7 +68,7 @@ declare_oxc_lint!( /// expect(Promise.resolve('Hi!')).resolves.toBe('Hi!'); /// ``` /// - /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md), + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/docs/rules/valid-expect.md), /// to use it, add the following configuration to your `.eslintrc.json`: /// /// ```json diff --git a/crates/oxc_linter/src/rules/jsx_a11y/lang.rs b/crates/oxc_linter/src/rules/jsx_a11y/lang.rs index 0cf7d34f41cbf1..f42b1a2ea4e9b1 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/lang.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/lang.rs @@ -51,7 +51,7 @@ declare_oxc_lint!( /// ``` /// /// ### Resources - /// - [eslint-plugin-jsx-a11y/lang](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/lang.md) + /// - [eslint-plugin-jsx-a11y/lang](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/docs/rules/lang.md) /// - [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry) Lang, correctness diff --git a/crates/oxc_linter/src/rules/jsx_a11y/role_supports_aria_props.rs b/crates/oxc_linter/src/rules/jsx_a11y/role_supports_aria_props.rs index d81d4547ab223b..7f2080d872a9aa 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/role_supports_aria_props.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/role_supports_aria_props.rs @@ -100,7 +100,7 @@ impl Rule for RoleSupportsAriaProps { } } -/// ref: <https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/getImplicitRole.js> +/// ref: <https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/src/util/getImplicitRole.js> fn get_implicit_role<'a>( node: &'a JSXOpeningElement<'a>, element_type: &str, diff --git a/crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs b/crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs index d3ad356b5fc9e0..b5c3fb7fc05c3b 100644 --- a/crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs +++ b/crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs @@ -38,7 +38,7 @@ declare_oxc_lint!( correctness ); -// Keep in sync with next.js polyfills file : https://github.com/vercel/next.js/blob/master/packages/next-polyfill-nomodule/src/index.js +// Keep in sync with next.js polyfills file : https://github.com/vercel/next.js/blob/v15.0.2/packages/next-polyfill-nomodule/src/index.js const NEXT_POLYFILLED_FEATURES: Set<&'static str> = phf_set! { "Array.prototype.@@iterator", "Array.prototype.at", diff --git a/crates/oxc_linter/src/rules/oxc/no_accumulating_spread.rs b/crates/oxc_linter/src/rules/oxc/no_accumulating_spread.rs index f9c89409746826..d0a6fa0fbcb72c 100644 --- a/crates/oxc_linter/src/rules/oxc/no_accumulating_spread.rs +++ b/crates/oxc_linter/src/rules/oxc/no_accumulating_spread.rs @@ -365,7 +365,7 @@ fn test() { } } ", - // source: https://github.com/biomejs/biome/blob/main/crates/biome_js_analyze/tests/specs/performance/noAccumulatingSpread/valid.jsonc#L3C1-L23C52 + // source: https://github.com/biomejs/biome/blob/cli/v1.9.4/crates/biome_js_analyze/tests/specs/performance/noAccumulatingSpread/valid.jsonc#L3C1-L23C52 "foo.reduce((acc, bar) => {acc.push(bar); return acc;}, [])", "foo.reduceRight((acc, bar) => {acc.push(bar); return acc;}, [])", // Array - Allow spreading the item into the accumulator @@ -420,7 +420,7 @@ fn test() { let temp = { ...acc, x } return temp }, {})", - // source https://github.com/biomejs/biome/blob/main/crates/biome_js_analyze/tests/specs/performance/noAccumulatingSpread/invalid.jsonc#L2-L32 + // source https://github.com/biomejs/biome/blob/cli/v1.9.4/crates/biome_js_analyze/tests/specs/performance/noAccumulatingSpread/invalid.jsonc#L2-L32 // Array - Arrow return "foo.reduce((acc, bar) => [...acc, bar], [])", "foo.reduceRight((acc, bar) => [...acc, bar], [])", diff --git a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs index c6baacfa659a70..ccd7e9d8163f9c 100644 --- a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs +++ b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs @@ -22,9 +22,9 @@ fn no_direct_mutation_state_diagnostic(span: Span) -> OxcDiagnostic { #[derive(Debug, Default, Clone)] pub struct NoDirectMutationState; -// code: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/lib/rules/no-direct-mutation-state.js -// doc: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md -// test: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/tests/lib/rules/no-direct-mutation-state.js +// code: https://github.com/jsx-eslint/eslint-plugin-react/blob/v7.37.2/lib/rules/no-direct-mutation-state.js +// doc: https://github.com/jsx-eslint/eslint-plugin-react/blob/v7.37.2/docs/rules/no-direct-mutation-state.md +// test: https://github.com/jsx-eslint/eslint-plugin-react/blob/v7.37.2/tests/lib/rules/no-direct-mutation-state.js declare_oxc_lint!( /// ### What it does diff --git a/crates/oxc_linter/src/rules/security/api_keys/mod.rs b/crates/oxc_linter/src/rules/security/api_keys/mod.rs index 3cc7178726d530..936e5e1392e004 100644 --- a/crates/oxc_linter/src/rules/security/api_keys/mod.rs +++ b/crates/oxc_linter/src/rules/security/api_keys/mod.rs @@ -72,7 +72,7 @@ declare_oxc_lint!( /// One possible alternative is to store secrets in a secure secrets manager /// (such as [AWS /// KMS](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/kms/), - /// [HashiCorp Vault](https://github.com/nodevault/node-vault/tree/master), + /// [HashiCorp Vault](https://github.com/nodevault/node-vault/tree/v0.10.2), /// [Pangea](https://pangea.cloud/docs/sdk/js/vault#retrieve), etc.) and /// request them when your application starts (e.g. a Docker container, an /// EC2). diff --git a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/mod.rs b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/mod.rs index 9d82923d225f0e..be2dab30c97f28 100644 --- a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/mod.rs +++ b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/mod.rs @@ -88,7 +88,7 @@ fn throw(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Throwing an error is a side-effect").with_label(span) } -/// <https://github.com/lukastaegert/eslint-plugin-tree-shaking/blob/master/src/rules/no-side-effects-in-initialization.ts> +/// <https://github.com/lukastaegert/eslint-plugin-tree-shaking/blob/v1.12.2/src/rules/no-side-effects-in-initialization.ts> #[derive(Debug, Default, Clone)] pub struct NoSideEffectsInInitialization(Box<NoSideEffectsInInitiallizationOptions>); diff --git a/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs b/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs index 49f81db637415b..13f1603b5fbbbb 100644 --- a/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs +++ b/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs @@ -47,7 +47,7 @@ impl Deref for ConsistentTypeImports { } } -/// <https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/consistent-type-imports.mdx> +/// <https://github.com/typescript-eslint/typescript-eslint/blob/v8.9.0/packages/eslint-plugin/docs/rules/consistent-type-imports.mdx> #[derive(Default, Debug, Clone)] pub struct ConsistentTypeImportsConfig { disallow_type_annotations: DisallowTypeAnnotations, diff --git a/crates/oxc_linter/src/utils/react.rs b/crates/oxc_linter/src/utils/react.rs index 1fcd235c16849d..ff9bf38f79a627 100644 --- a/crates/oxc_linter/src/utils/react.rs +++ b/crates/oxc_linter/src/utils/react.rs @@ -60,7 +60,7 @@ pub fn get_string_literal_prop_value<'a>(item: &'a JSXAttributeItem<'_>) -> Opti get_prop_value(item).and_then(JSXAttributeValue::as_string_literal).map(|s| s.value.as_str()) } -// ref: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/isHiddenFromScreenReader.js +// ref: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/src/util/isHiddenFromScreenReader.js pub fn is_hidden_from_screen_reader<'a>( ctx: &LintContext<'a>, node: &JSXOpeningElement<'a>, @@ -91,7 +91,7 @@ pub fn is_hidden_from_screen_reader<'a>( }) } -// ref: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/hasAccessibleChild.js +// ref: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/src/util/hasAccessibleChild.js pub fn object_has_accessible_child<'a>(ctx: &LintContext<'a>, node: &JSXElement<'a>) -> bool { node.children.iter().any(|child| match child { JSXChild::Text(text) => !text.value.is_empty(), @@ -206,7 +206,7 @@ pub fn get_parent_component<'a, 'b>( /// Resolve element type(name) using jsx-a11y settings /// ref: -/// <https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/getElementType.js> +/// <https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/src/util/getElementType.js> pub fn get_element_type<'c, 'a>( context: &'c LintContext<'a>, element: &JSXOpeningElement<'a>, diff --git a/crates/oxc_linter/src/utils/unicorn.rs b/crates/oxc_linter/src/utils/unicorn.rs index 3806039ddb34e7..77e5c5d65bd5bf 100644 --- a/crates/oxc_linter/src/utils/unicorn.rs +++ b/crates/oxc_linter/src/utils/unicorn.rs @@ -39,7 +39,7 @@ pub fn is_empty_stmt(stmt: &Statement) -> bool { } } -// ref: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/rules/utils/array-or-object-prototype-property.js +// ref: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v56.0.0/rules/utils/array-or-object-prototype-property.js pub fn is_prototype_property( member_expr: &MemberExpression, property: &str, diff --git a/crates/oxc_mangler/src/lib.rs b/crates/oxc_mangler/src/lib.rs index dfabd1e431ebb1..cb6b085cb14be1 100644 --- a/crates/oxc_mangler/src/lib.rs +++ b/crates/oxc_mangler/src/lib.rs @@ -14,7 +14,7 @@ pub struct MangleOptions { /// # Name Mangler / Symbol Minification /// /// See: -/// * [esbuild](https://github.com/evanw/esbuild/blob/main/docs/architecture.md#symbol-minification) +/// * [esbuild](https://github.com/evanw/esbuild/blob/v0.24.0/docs/architecture.md#symbol-minification) /// /// This algorithm is targeted for better gzip compression. /// diff --git a/crates/oxc_minifier/README.md b/crates/oxc_minifier/README.md index f88e8ca6f2422f..68b504ed7b4d61 100644 --- a/crates/oxc_minifier/README.md +++ b/crates/oxc_minifier/README.md @@ -20,4 +20,4 @@ The compressor is responsible for rewriting statements and expressions for minim ## Terser Tests -The fixtures are copied from https://github.com/terser/terser/tree/master/test/compress +The fixtures are copied from https://github.com/terser/terser/tree/v5.9.0/test/compress diff --git a/crates/oxc_minifier/src/ast_passes/collapse_variable_declarations.rs b/crates/oxc_minifier/src/ast_passes/collapse_variable_declarations.rs index c7e9de1c449cd5..dd074e7a4c5bd6 100644 --- a/crates/oxc_minifier/src/ast_passes/collapse_variable_declarations.rs +++ b/crates/oxc_minifier/src/ast_passes/collapse_variable_declarations.rs @@ -7,7 +7,7 @@ use crate::CompressorPass; /// Collapse variable declarations. /// /// `var a; var b = 1; var c = 2` => `var a, b = 1; c = 2` -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/CollapseVariableDeclarations.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/CollapseVariableDeclarations.java> pub struct CollapseVariableDeclarations { changed: bool, } @@ -108,7 +108,7 @@ impl<'a> CollapseVariableDeclarations { } } -/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/CollapseVariableDeclarationsTest.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/CollapseVariableDeclarationsTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/exploit_assigns.rs b/crates/oxc_minifier/src/ast_passes/exploit_assigns.rs index 84b5783b13b756..50558bd8cc4a85 100644 --- a/crates/oxc_minifier/src/ast_passes/exploit_assigns.rs +++ b/crates/oxc_minifier/src/ast_passes/exploit_assigns.rs @@ -5,7 +5,7 @@ use crate::CompressorPass; /// Tries to chain assignments together. /// -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/ExploitAssigns.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/ExploitAssigns.java> pub struct ExploitAssigns { changed: bool, } @@ -29,7 +29,7 @@ impl ExploitAssigns { } } -/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/ExploitAssignsTest.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/ExploitAssignsTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs index d7397ff5c24358..282ddbe102f835 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs @@ -14,7 +14,7 @@ use crate::{node_util::Ctx, CompressorPass}; /// Constant Folding /// -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeFoldConstants.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeFoldConstants.java> pub struct PeepholeFoldConstants { changed: bool, } @@ -449,7 +449,7 @@ impl<'a, 'b> PeepholeFoldConstants { } } -/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeFoldConstantsTest.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeFoldConstantsTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; @@ -1158,7 +1158,7 @@ mod test { test("1 << -1", "1<<-1"); test("1 >> 32", "1>>32"); - // Regression on #6161, ported from <https://github.com/tc39/test262/blob/main/test/language/expressions/unsigned-right-shift/S9.6_A2.2.js>. + // Regression on #6161, ported from <https://github.com/tc39/test262/blob/05c45a4c430ab6fee3e0c7f0d47d8a30d8876a6d/test/language/expressions/unsigned-right-shift/S9.6_A2.2.js>. test("-2147483647 >>> 0", "2147483649"); test("-2147483648 >>> 0", "2147483648"); test("-2147483649 >>> 0", "2147483647"); diff --git a/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs b/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs index 8bcd18bbf2e25b..1b0bb1bbea176a 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs @@ -9,7 +9,7 @@ use crate::CompressorPass; /// Also rewrites conditional statements as expressions by replacing them /// with `? :` and short-circuit binary operators. /// -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeMinimizeConditions.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeMinimizeConditions.java> pub struct PeepholeMinimizeConditions { changed: bool, } @@ -58,7 +58,7 @@ impl<'a> PeepholeMinimizeConditions { } } -/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeMinimizeConditionsTest.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeMinimizeConditionsTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs index 3f9c1d1d30b02a..e92be6327d3b7f 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs @@ -12,7 +12,7 @@ use crate::{keep_var::KeepVar, CompressorPass}; /// Terser option: `dead_code: true`. /// /// See `KeepVar` at the end of this file for `var` hoisting logic. -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java> pub struct PeepholeRemoveDeadCode { changed: bool, } @@ -417,7 +417,7 @@ impl<'a, 'b> PeepholeRemoveDeadCode { } } -/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeRemoveDeadCodeTest.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeRemoveDeadCodeTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/peephole_replace_known_methods.rs b/crates/oxc_minifier/src/ast_passes/peephole_replace_known_methods.rs index 5b9e67a5da11aa..4a8b044b0a74f9 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_replace_known_methods.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_replace_known_methods.rs @@ -9,7 +9,7 @@ use oxc_traverse::{Traverse, TraverseCtx}; use crate::{node_util::Ctx, CompressorPass}; /// Minimize With Known Methods -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeReplaceKnownMethods.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeReplaceKnownMethods.java> pub struct PeepholeReplaceKnownMethods { changed: bool, } @@ -269,7 +269,7 @@ impl PeepholeReplaceKnownMethods { } } -/// Port from: <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeReplaceKnownMethodsTest.java> +/// Port from: <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeReplaceKnownMethodsTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs index 381db25a375e0f..dcd52b3eb3e570 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs @@ -14,7 +14,7 @@ use crate::{node_util::Ctx, CompressorPass}; /// A peephole optimization that minimizes code by simplifying conditional /// expressions, replacing IFs with HOOKs, replacing object constructors /// with literals, and simplifying returns. -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntax.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntax.java> pub struct PeepholeSubstituteAlternateSyntax { /// Do not compress syntaxes that are hard to analyze inside the fixed loop. /// e.g. Do not compress `undefined -> void 0`, `true` -> `!0`. @@ -566,7 +566,7 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax { } } -/// Port from <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java> +/// Port from <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java> #[cfg(test)] mod test { use oxc_allocator::Allocator; diff --git a/crates/oxc_minifier/src/ast_passes/statement_fusion.rs b/crates/oxc_minifier/src/ast_passes/statement_fusion.rs index 05531760ae57f3..3b3e497639838d 100644 --- a/crates/oxc_minifier/src/ast_passes/statement_fusion.rs +++ b/crates/oxc_minifier/src/ast_passes/statement_fusion.rs @@ -10,7 +10,7 @@ use crate::CompressorPass; /// /// Tries to fuse all the statements in a block into a one statement by using COMMAs or statements. /// -/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/StatementFusion.java> +/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/StatementFusion.java> pub struct StatementFusion { changed: bool, } diff --git a/crates/oxc_minifier/tests/ast_passes/dead_code_elimination.rs b/crates/oxc_minifier/tests/ast_passes/dead_code_elimination.rs index 6b5e777fc29d89..f366e3fc60ae0a 100644 --- a/crates/oxc_minifier/tests/ast_passes/dead_code_elimination.rs +++ b/crates/oxc_minifier/tests/ast_passes/dead_code_elimination.rs @@ -155,7 +155,7 @@ fn dce_var_hoisting() { ); } -// https://github.com/terser/terser/blob/master/test/compress/dead-code.js +// https://github.com/terser/terser/blob/v5.9.0/test/compress/dead-code.js #[test] fn dce_from_terser() { test( diff --git a/crates/oxc_module_lexer/tests/integration/esm.rs b/crates/oxc_module_lexer/tests/integration/esm.rs index 2e84808cedd8b5..618d0410e21c10 100644 --- a/crates/oxc_module_lexer/tests/integration/esm.rs +++ b/crates/oxc_module_lexer/tests/integration/esm.rs @@ -1,4 +1,4 @@ -//! <https://github.com/guybedford/es-module-lexer/blob/main/test/_unit.cjs> +//! <https://github.com/guybedford/es-module-lexer/blob/1.5.4/test/_unit.cjs> use oxc_allocator::Allocator; use oxc_module_lexer::ImportType; diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index 5a668fe4d63ec5..12e61c17f79c37 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -48,7 +48,7 @@ impl<'a> ParserImpl<'a> { // Section 11.2.1 Directive Prologue // The only way to get a correct directive is to parse the statement first and check if it is a string literal. - // All other method are flawed, see test cases in [babel](https://github.com/babel/babel/blob/main/packages/babel-parser/test/fixtures/core/categorized/not-directive/input.js) + // All other method are flawed, see test cases in [babel](https://github.com/babel/babel/blob/v7.26.2/packages/babel-parser/test/fixtures/core/categorized/not-directive/input.js) if expecting_directives { if let Statement::ExpressionStatement(expr) = &stmt { if let Expression::StringLiteral(string) = &expr.expression { diff --git a/crates/oxc_parser/src/lexer/byte_handlers.rs b/crates/oxc_parser/src/lexer/byte_handlers.rs index b7102a89fa8cff..140b60b6aced83 100644 --- a/crates/oxc_parser/src/lexer/byte_handlers.rs +++ b/crates/oxc_parser/src/lexer/byte_handlers.rs @@ -15,7 +15,7 @@ pub(super) unsafe fn handle_byte(byte: u8, lexer: &mut Lexer) -> Kind { type ByteHandler = unsafe fn(&mut Lexer<'_>) -> Kind; /// Lookup table mapping any incoming byte to a handler function defined below. -/// <https://github.com/ratel-rust/ratel-core/blob/master/ratel/src/lexer/mod.rs> +/// <https://github.com/ratel-rust/ratel-core/blob/v0.7.0/ratel/src/lexer/mod.rs> #[rustfmt::skip] static BYTE_HANDLERS: [ByteHandler; 256] = [ // 0 1 2 3 4 5 6 7 8 9 A B C D E F // diff --git a/crates/oxc_parser/src/lexer/mod.rs b/crates/oxc_parser/src/lexer/mod.rs index 1e11d5b619e5d0..35ba4cb5b663a0 100644 --- a/crates/oxc_parser/src/lexer/mod.rs +++ b/crates/oxc_parser/src/lexer/mod.rs @@ -3,9 +3,9 @@ //! An Ecma-262 Lexer / Tokenizer //! Prior Arts: -//! * [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/parser/src) -//! * [rome](https://github.com/rome/tools/tree/main/crates/rome_js_parser/src/lexer) -//! * [rustc](https://github.com/rust-lang/rust/blob/master/compiler/rustc_lexer/src) +//! * [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/24004745a8ed4939fc0dc7332bfd1268ac52285f/crates/parser/src) +//! * [rome](https://github.com/rome/tools/tree/lsp/v0.28.0/crates/rome_js_parser/src/lexer) +//! * [rustc](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_lexer/src) //! * [v8](https://v8.dev/blog/scanner) mod byte_handlers; diff --git a/crates/oxc_parser/src/lexer/number.rs b/crates/oxc_parser/src/lexer/number.rs index c69df154f49fde..6fda36de5410c1 100644 --- a/crates/oxc_parser/src/lexer/number.rs +++ b/crates/oxc_parser/src/lexer/number.rs @@ -1,6 +1,6 @@ //! Parsing utilities for converting Javascript numbers to Rust f64. //! Code copied originally from -//! [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/crates/parser/src/numeric_value.rs) +//! [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus/blob/24004745a8ed4939fc0dc7332bfd1268ac52285f/crates/parser/src/numeric_value.rs) //! but iterated on since. use std::borrow::Cow; diff --git a/crates/oxc_prettier/README.md b/crates/oxc_prettier/README.md index 947e226a876ad2..4382114e4fec35 100644 --- a/crates/oxc_prettier/README.md +++ b/crates/oxc_prettier/README.md @@ -7,4 +7,4 @@ Create a `test.js` and run the example `just example prettier` from `crates/oxc_ - [x] Have the basic infrastructure ready for contribution - [x] Implement a test runner in Rust which extracts the snapshots and do a comparison over it - [x] Establish a way to pass all the tests by manually porting code -- [ ] Pass as many tests as possible in https://github.com/prettier/prettier/tree/main/tests/format/js +- [ ] Pass as many tests as possible in https://github.com/prettier/prettier/tree/3.3.3/tests/format/js diff --git a/crates/oxc_prettier/src/doc.rs b/crates/oxc_prettier/src/doc.rs index 417d7a3e78fc90..651e0922a5d377 100644 --- a/crates/oxc_prettier/src/doc.rs +++ b/crates/oxc_prettier/src/doc.rs @@ -1,7 +1,7 @@ //! Prettier IR //! //! References: -//! * <https://github.com/prettier/prettier/blob/main/commands.md> +//! * <https://github.com/prettier/prettier/blob/3.3.3/commands.md> use std::fmt; @@ -218,7 +218,7 @@ impl<'a> fmt::Display for Doc<'a> { } } -// https://github.com/prettier/prettier/blob/main/src/document/debug.js +// https://github.com/prettier/prettier/blob/3.3.3/src/document/debug.js fn print_doc_to_debug(doc: &Doc<'_>) -> std::string::String { use std::string::String; let mut string = String::new(); diff --git a/crates/oxc_prettier/src/format/call_arguments.rs b/crates/oxc_prettier/src/format/call_arguments.rs index fcc278320fa0ee..3845dda8baf8b9 100644 --- a/crates/oxc_prettier/src/format/call_arguments.rs +++ b/crates/oxc_prettier/src/format/call_arguments.rs @@ -178,7 +178,7 @@ pub fn print_call_arguments<'a>( Doc::Group(Group::new(parts).with_break(should_break)) } -/// * Reference <https://github.com/prettier/prettier/blob/main/src/language-js/print/call-arguments.js#L247-L272> +/// * Reference <https://github.com/prettier/prettier/blob/3.3.3/src/language-js/print/call-arguments.js#L247-L272> fn should_expand_first_arg<'a>(arguments: &Vec<'a, Argument<'a>>) -> bool { if arguments.len() != 2 { return false; diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index bf2e9f9eb11050..d1c794111cbbd0 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -1,7 +1,7 @@ //! Formatting logic //! //! References: -//! * <https://github.com/prettier/prettier/blob/main/src/language-js/print/estree.js> +//! * <https://github.com/prettier/prettier/blob/3.3.3/src/language-js/print/estree.js> #![allow(unused_variables)] @@ -1789,7 +1789,7 @@ impl<'a> Format<'a> for NullLiteral { impl<'a> Format<'a> for NumericLiteral<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { wrap!(p, self, NumericLiteral, { - // See https://github.com/prettier/prettier/blob/main/src/utils/print-number.js + // See https://github.com/prettier/prettier/blob/3.3.3/src/utils/print-number.js // Perf: the regexes from prettier code above are ported to manual search for performance reasons. let mut string = self.span.source_text(p.source_text).cow_to_ascii_lowercase(); diff --git a/crates/oxc_prettier/src/lib.rs b/crates/oxc_prettier/src/lib.rs index d82ecfddf139f1..fe09665c3e184b 100644 --- a/crates/oxc_prettier/src/lib.rs +++ b/crates/oxc_prettier/src/lib.rs @@ -54,7 +54,7 @@ pub struct Prettier<'a> { options: PrettierOptions, /// The stack of AST Nodes - /// See <https://github.com/prettier/prettier/blob/main/src/common/ast-path.js> + /// See <https://github.com/prettier/prettier/blob/3.3.3/src/common/ast-path.js> stack: Vec<AstKind<'a>>, group_id_builder: GroupIdBuilder, diff --git a/crates/oxc_prettier/src/needs_parens.rs b/crates/oxc_prettier/src/needs_parens.rs index 1698ec3b427599..71a65e8e8b62d0 100644 --- a/crates/oxc_prettier/src/needs_parens.rs +++ b/crates/oxc_prettier/src/needs_parens.rs @@ -1,6 +1,6 @@ //! Direct port of needs-parens for adding or removing parentheses. //! -//! See <https://github.com/prettier/prettier/blob/main/src/language-js/needs-parens.js> +//! See <https://github.com/prettier/prettier/blob/3.3.3/src/language-js/needs-parens.js> #![allow( clippy::unused_self, diff --git a/crates/oxc_prettier/src/options.rs b/crates/oxc_prettier/src/options.rs index b9f36f41e62e6a..53dda9bfec5d1a 100644 --- a/crates/oxc_prettier/src/options.rs +++ b/crates/oxc_prettier/src/options.rs @@ -4,8 +4,8 @@ use std::str::FromStr; /// /// References /// * <https://prettier.io/docs/en/options> -/// * <https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js> -/// * <https://github.com/prettier/prettier/blob/main/src/language-js/options.js> +/// * <https://github.com/prettier/prettier/blob/3.3.3/src/main/core-options.evaluate.js> +/// * <https://github.com/prettier/prettier/blob/3.3.3/src/language-js/options.js> #[derive(Debug, Clone, Copy)] pub struct PrettierOptions { /* Global Options */ diff --git a/crates/oxc_prettier/src/printer/mod.rs b/crates/oxc_prettier/src/printer/mod.rs index d3103cbfe1e10c..35525a90e69185 100644 --- a/crates/oxc_prettier/src/printer/mod.rs +++ b/crates/oxc_prettier/src/printer/mod.rs @@ -1,7 +1,7 @@ //! [Doc] Printer //! //! References: -//! * <https://github.com/prettier/prettier/blob/main/src/document/printer.js> +//! * <https://github.com/prettier/prettier/blob/3.3.3/src/document/printer.js> mod command; @@ -440,7 +440,7 @@ impl<'a> Printer<'a> { } /// Reference: - /// * <https://github.com/prettier/prettier/blob/main/src/document/utils.js#L156-L185> + /// * <https://github.com/prettier/prettier/blob/3.3.3/src/document/utils.js#L156-L185> pub fn propagate_breaks(doc: &mut Doc<'_>) -> bool { let check_array = |arr: &mut oxc_allocator::Vec<'_, Doc<'_>>| { arr.iter_mut().rev().any(|doc| Self::propagate_breaks(doc)) diff --git a/crates/oxc_sourcemap/src/decode.rs b/crates/oxc_sourcemap/src/decode.rs index fcbbc06f3fbe03..95ff8fff46bb74 100644 --- a/crates/oxc_sourcemap/src/decode.rs +++ b/crates/oxc_sourcemap/src/decode.rs @@ -1,11 +1,11 @@ -/// Port from https://github.com/getsentry/rust-sourcemap/blob/master/src/decoder.rs +/// Port from https://github.com/getsentry/rust-sourcemap/blob/9.1.0/src/decoder.rs /// It is a helper for decode vlq soucemap string to `SourceMap`. use std::sync::Arc; use crate::error::{Error, Result}; use crate::{SourceMap, Token}; -/// See <https://github.com/tc39/source-map/blob/main/source-map-rev3.md>. +/// See <https://github.com/tc39/source-map/blob/1930e58ffabefe54038f7455759042c6e3dd590e/source-map-rev3.md>. #[derive(serde::Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct JSONSourceMap { diff --git a/crates/oxc_sourcemap/src/encode.rs b/crates/oxc_sourcemap/src/encode.rs index 356ce4f1e6df89..7bc27686a2068f 100644 --- a/crates/oxc_sourcemap/src/encode.rs +++ b/crates/oxc_sourcemap/src/encode.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use rayon::prelude::*; use crate::JSONSourceMap; -/// Port from https://github.com/getsentry/rust-sourcemap/blob/master/src/encoder.rs +/// Port from https://github.com/getsentry/rust-sourcemap/blob/9.1.0/src/encoder.rs /// It is a helper for encode `SourceMap` to vlq sourcemap string, but here some different. /// - Quote `source_content` at parallel. /// - If you using `ConcatSourceMapBuilder`, serialize `tokens` to vlq `mappings` at parallel. diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 10e3a3c62452ce..a4ba256f342eb8 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -31,7 +31,7 @@ //! helperName(...arguments); //! ``` //! -//! Based on [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-runtime). +//! Based on [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-runtime). //! //! ### External ([`HelperLoaderMode::External`]) //! @@ -43,7 +43,7 @@ //! babelHelpers.helperName(...arguments); //! ``` //! -//! Based on [@babel/plugin-external-helpers](https://github.com/babel/babel/tree/main/packages/babel-plugin-external-helpers). +//! Based on [@babel/plugin-external-helpers](https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-external-helpers). //! //! ### Inline ([`HelperLoaderMode::Inline`]) //! @@ -58,7 +58,7 @@ //! helperName(...arguments); //! ``` //! -//! Based on [@babel/helper](https://github.com/babel/babel/tree/main/packages/babel-helpers). +//! Based on [@babel/helper](https://github.com/babel/babel/tree/v7.26.2/packages/babel-helpers). //! //! ## Implementation //! diff --git a/crates/oxc_transformer/src/common/module_imports.rs b/crates/oxc_transformer/src/common/module_imports.rs index 94c4c2a1830b21..87a64a311d548e 100644 --- a/crates/oxc_transformer/src/common/module_imports.rs +++ b/crates/oxc_transformer/src/common/module_imports.rs @@ -30,7 +30,7 @@ //! > NOTE: Using `import` or `require` is determined by [`TransformCtx::source_type`]. //! //! Based on `@babel/helper-module-imports` -//! <https://github.com/nicolo-ribaudo/babel/tree/main/packages/babel-helper-module-imports> +//! <https://github.com/nicolo-ribaudo/babel/tree/v7.25.8/packages/babel-helper-module-imports> use std::cell::RefCell; diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index a0779dd52a5e83..a6ae357f2c2b02 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -122,7 +122,7 @@ //! //! ## References: //! -//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-arrow-functions> +//! * Babel plugin implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-arrow-functions> //! * Arrow function specification: <https://tc39.es/ecma262/#sec-arrow-function-definitions> use serde::Deserialize; diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index 716ade8cf25dd4..38254c188783dd 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -27,8 +27,8 @@ //! ## References: //! //! * Babel plugin implementation: -//! <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-exponentiation-operator> -//! <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-binary-assignment-operator-visitor> +//! <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-exponentiation-operator> +//! <https://github.com/babel/babel/tree/v7.26.2/packages/babel-helper-builder-binary-assignment-operator-visitor> //! * Exponentiation operator TC39 proposal: <https://github.com/tc39/proposal-exponentiation-operator> //! * Exponentiation operator specification: <https://tc39.es/ecma262/#sec-exp-operator> diff --git a/crates/oxc_transformer/src/es2017/async_to_generator.rs b/crates/oxc_transformer/src/es2017/async_to_generator.rs index c7107ee576cc75..9e8729f59fe8a3 100644 --- a/crates/oxc_transformer/src/es2017/async_to_generator.rs +++ b/crates/oxc_transformer/src/es2017/async_to_generator.rs @@ -48,7 +48,7 @@ //! //! Reference: //! * Babel docs: <https://babeljs.io/docs/en/babel-plugin-transform-async-to-generator> -//! * Babel implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-async-to-generator> +//! * Babel implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-async-to-generator> //! * Async / Await TC39 proposal: <https://github.com/tc39/proposal-async-await> use std::mem; diff --git a/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs b/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs index 1b0d5c93291158..45a2847a772747 100644 --- a/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs +++ b/crates/oxc_transformer/src/es2018/async_generator_functions/mod.rs @@ -61,7 +61,7 @@ //! //! Reference: //! * Babel docs: <https://babeljs.io/docs/en/babel-plugin-transform-async-generator-functions> -//! * Babel implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-async-generator-functions> +//! * Babel implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-async-generator-functions> //! * Async Iteration TC39 proposal: <https://github.com/tc39/proposal-async-iteration> mod for_await; diff --git a/crates/oxc_transformer/src/es2018/object_rest_spread.rs b/crates/oxc_transformer/src/es2018/object_rest_spread.rs index 0daaf88ca3aa2c..39963df9871864 100644 --- a/crates/oxc_transformer/src/es2018/object_rest_spread.rs +++ b/crates/oxc_transformer/src/es2018/object_rest_spread.rs @@ -23,7 +23,7 @@ //! Implementation based on [@babel/plugin-transform-object-rest-spread](https://babeljs.io/docs/babel-plugin-transform-object-rest-spread). //! //! ## References: -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-object-rest-spread> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-object-rest-spread> //! * Object rest/spread TC39 proposal: <https://github.com/tc39/proposal-object-rest-spread> use serde::Deserialize; diff --git a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs index 5d9d98eda40cf5..304ced8b7fadbb 100644 --- a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs +++ b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs @@ -30,7 +30,7 @@ //! Implementation based on [@babel/plugin-transform-optional-catch-binding](https://babel.dev/docs/babel-plugin-transform-optional-catch-binding). //! //! ## References: -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-optional-catch-binding> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-optional-catch-binding> //! * Optional catch binding TC39 proposal: <https://github.com/tc39/proposal-optional-catch-binding> use oxc_ast::ast::*; diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 50dc3b59499418..ecefb0fe8def0b 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -25,7 +25,7 @@ //! Implementation based on [@babel/plugin-transform-nullish-coalescing-operator](https://babeljs.io/docs/babel-plugin-transform-nullish-coalescing-operator). //! //! ## References: -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-nullish-coalescing-operator> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-nullish-coalescing-operator> //! * Nullish coalescing TC39 proposal: <https://github.com/tc39-transfer/proposal-nullish-coalescing> use oxc_allocator::Box as ArenaBox; diff --git a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs index e2e8fbf4f491de..a06d2bb8dd4522 100644 --- a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs +++ b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs @@ -51,7 +51,7 @@ //! Implementation based on [@babel/plugin-transform-logical-assignment-operators](https://babel.dev/docs/babel-plugin-transform-logical-assignment-operators). //! //! ## References: -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-logical-assignment-operators> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-logical-assignment-operators> //! * Logical Assignment TC39 proposal: <https://github.com/tc39/proposal-logical-assignment> use oxc_allocator::CloneIn; diff --git a/crates/oxc_transformer/src/es2022/class_properties.rs b/crates/oxc_transformer/src/es2022/class_properties.rs index 5087d26aa86c34..becd2424c9f246 100644 --- a/crates/oxc_transformer/src/es2022/class_properties.rs +++ b/crates/oxc_transformer/src/es2022/class_properties.rs @@ -57,9 +57,9 @@ //! //! ## References: //! * Babel plugin implementation: -//! * <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-class-properties> -//! * <https://github.com/babel/babel/blob/main/packages/babel-helper-create-class-features-plugin/src/index.ts> -//! * <https://github.com/babel/babel/blob/main/packages/babel-helper-create-class-features-plugin/src/fields.ts> +//! * <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-class-properties> +//! * <https://github.com/babel/babel/blob/v7.26.2/packages/babel-helper-create-class-features-plugin/src/index.ts> +//! * <https://github.com/babel/babel/blob/v7.26.2/packages/babel-helper-create-class-features-plugin/src/fields.ts> //! * Class properties TC39 proposal: <https://github.com/tc39/proposal-class-fields> use serde::Deserialize; diff --git a/crates/oxc_transformer/src/es2022/class_static_block.rs b/crates/oxc_transformer/src/es2022/class_static_block.rs index f19ec629652da2..c1aaf5c26855c6 100644 --- a/crates/oxc_transformer/src/es2022/class_static_block.rs +++ b/crates/oxc_transformer/src/es2022/class_static_block.rs @@ -36,7 +36,7 @@ //! Implementation based on [@babel/plugin-transform-class-static-block](https://babel.dev/docs/babel-plugin-transform-class-static-block). //! //! ## References: -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-class-static-block> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-plugin-transform-class-static-block> //! * Class static initialization blocks TC39 proposal: <https://github.com/tc39/proposal-class-static-block> use itoa::Buffer as ItoaBuffer; diff --git a/crates/oxc_transformer/src/jsx/display_name.rs b/crates/oxc_transformer/src/jsx/display_name.rs index f37b0d1154e7a2..05b9c92c0374ed 100644 --- a/crates/oxc_transformer/src/jsx/display_name.rs +++ b/crates/oxc_transformer/src/jsx/display_name.rs @@ -43,7 +43,7 @@ //! //! ## References: //! -//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-display-name/src/index.ts> +//! * Babel plugin implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-react-display-name/src/index.ts> use oxc_ast::ast::*; use oxc_span::{Atom, SPAN}; diff --git a/crates/oxc_transformer/src/jsx/jsx_impl.rs b/crates/oxc_transformer/src/jsx/jsx_impl.rs index db972b6b511a47..8d58728d9be144 100644 --- a/crates/oxc_transformer/src/jsx/jsx_impl.rs +++ b/crates/oxc_transformer/src/jsx/jsx_impl.rs @@ -86,7 +86,7 @@ //! //! ## References: //! -//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-react-jsx> +//! * Babel plugin implementation: <https://github.com/babel/babel/tree/v7.26.2/packages/babel-helper-builder-react-jsx> use oxc_allocator::Vec as ArenaVec; use oxc_ast::{ast::*, AstBuilder, NONE}; diff --git a/crates/oxc_transformer/src/jsx/jsx_self.rs b/crates/oxc_transformer/src/jsx/jsx_self.rs index 8c90fdfd91dc93..940f84fc35c6e0 100644 --- a/crates/oxc_transformer/src/jsx/jsx_self.rs +++ b/crates/oxc_transformer/src/jsx/jsx_self.rs @@ -26,7 +26,7 @@ //! //! ## References: //! -//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-jsx-self/src/index.ts> +//! * Babel plugin implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-react-jsx-self/src/index.ts> use oxc_ast::ast::*; use oxc_diagnostics::OxcDiagnostic; diff --git a/crates/oxc_transformer/src/jsx/jsx_source.rs b/crates/oxc_transformer/src/jsx/jsx_source.rs index 950473b35a3e71..232cc4fba99ee6 100644 --- a/crates/oxc_transformer/src/jsx/jsx_source.rs +++ b/crates/oxc_transformer/src/jsx/jsx_source.rs @@ -31,7 +31,7 @@ //! //! ## References: //! -//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-react-jsx-source/src/index.ts> +//! * Babel plugin implementation: <https://github.com/babel/babel/blob/v7.26.2/packages/babel-plugin-transform-react-jsx-source/src/index.ts> use ropey::Rope; diff --git a/crates/oxc_transformer/src/jsx/refresh.rs b/crates/oxc_transformer/src/jsx/refresh.rs index 0598d5150719e5..a7145f0d06660f 100644 --- a/crates/oxc_transformer/src/jsx/refresh.rs +++ b/crates/oxc_transformer/src/jsx/refresh.rs @@ -99,7 +99,7 @@ impl<'a> RefreshIdentifierResolver<'a> { /// References: /// /// * <https://github.com/facebook/react/issues/16604#issuecomment-528663101> -/// * <https://github.com/facebook/react/blob/main/packages/react-refresh/src/ReactFreshBabelPlugin.js> +/// * <https://github.com/facebook/react/blob/v18.3.1/packages/react-refresh/src/ReactFreshBabelPlugin.js> pub struct ReactRefresh<'a, 'ctx> { refresh_reg: RefreshIdentifierResolver<'a>, refresh_sig: RefreshIdentifierResolver<'a>, diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index dd321309b39e68..474564f4339b0c 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -3,7 +3,7 @@ //! References: //! * <https://www.typescriptlang.org/tsconfig#target> //! * <https://babel.dev/docs/presets> -//! * <https://github.com/microsoft/TypeScript/blob/main/src/compiler/transformer.ts> +//! * <https://github.com/microsoft/TypeScript/blob/v5.6.3/src/compiler/transformer.ts> use std::path::Path; diff --git a/crates/oxc_transformer/tests/integrations/plugins/inject_global_variables.rs b/crates/oxc_transformer/tests/integrations/plugins/inject_global_variables.rs index 26ee7e9b6b0eb6..03835d70ed99ae 100644 --- a/crates/oxc_transformer/tests/integrations/plugins/inject_global_variables.rs +++ b/crates/oxc_transformer/tests/integrations/plugins/inject_global_variables.rs @@ -1,6 +1,6 @@ //! References //! -//! * <https://github.com/rollup/plugins/tree/master/packages/inject/test> +//! * <https://github.com/rollup/plugins/tree/pluginutils-v5.1.3/packages/inject/test> use oxc_allocator::Allocator; use oxc_codegen::{CodeGenerator, CodegenOptions}; diff --git a/napi/parser/index.d.ts b/napi/parser/index.d.ts index d2bc98de30bf34..a36ba4bec60909 100644 --- a/napi/parser/index.d.ts +++ b/napi/parser/index.d.ts @@ -102,7 +102,7 @@ export interface ParseResult { /** * Babel Parser Options * - * <https://github.com/babel/babel/blob/main/packages/babel-parser/typings/babel-parser.d.ts> + * <https://github.com/babel/babel/blob/v7.26.2/packages/babel-parser/typings/babel-parser.d.ts> */ export interface ParserOptions { sourceType?: 'script' | 'module' | 'unambiguous' | undefined diff --git a/napi/transform/index.d.ts b/napi/transform/index.d.ts index 4c76416ab66b9a..9fd1aca75d5cbc 100644 --- a/napi/transform/index.d.ts +++ b/napi/transform/index.d.ts @@ -127,7 +127,7 @@ export interface JsxOptions { /** * Enable React Fast Refresh . * - * Conforms to the implementation in {@link https://github.com/facebook/react/tree/main/packages/react-refresh} + * Conforms to the implementation in {@link https://github.com/facebook/react/tree/v18.3.1/packages/react-refresh} * * @default false */ diff --git a/npm/oxc-parser/scripts/generate-packages.mjs b/npm/oxc-parser/scripts/generate-packages.mjs index 624450780c3096..30a064712a322e 100644 --- a/npm/oxc-parser/scripts/generate-packages.mjs +++ b/npm/oxc-parser/scripts/generate-packages.mjs @@ -1,4 +1,4 @@ -// Code copied from [Rome](https://github.com/rome/tools/blob/main/npm/rome/scripts/generate-packages.mjs) +// Code copied from [Rome](https://github.com/rome/tools/blob/lsp/v0.28.0/npm/rome/scripts/generate-packages.mjs) import * as fs from 'node:fs'; import { resolve } from 'node:path'; diff --git a/npm/oxc-transform/scripts/generate-packages.mjs b/npm/oxc-transform/scripts/generate-packages.mjs index 555ebc0492ebe2..5205fef3ca81f3 100644 --- a/npm/oxc-transform/scripts/generate-packages.mjs +++ b/npm/oxc-transform/scripts/generate-packages.mjs @@ -1,4 +1,4 @@ -// Code copied from [Rome](https://github.com/rome/tools/blob/main/npm/rome/scripts/generate-packages.mjs) +// Code copied from [Rome](https://github.com/rome/tools/blob/lsp/v0.28.0/npm/rome/scripts/generate-packages.mjs) import * as fs from 'node:fs'; import { resolve } from 'node:path'; diff --git a/npm/oxlint/scripts/generate-packages.mjs b/npm/oxlint/scripts/generate-packages.mjs index 7768b560ff4583..e1c74af6feec95 100644 --- a/npm/oxlint/scripts/generate-packages.mjs +++ b/npm/oxlint/scripts/generate-packages.mjs @@ -1,4 +1,4 @@ -// Code copied from [Rome](https://github.com/rome/tools/blob/main/npm/rome/scripts/generate-packages.mjs) +// Code copied from [Rome](https://github.com/rome/tools/blob/lsp/v0.28.0/npm/rome/scripts/generate-packages.mjs) import * as fs from 'node:fs'; import { resolve } from 'node:path'; diff --git a/tasks/ast_tools/src/generators/visit.rs b/tasks/ast_tools/src/generators/visit.rs index a3df85f3a0e596..97b64535573417 100644 --- a/tasks/ast_tools/src/generators/visit.rs +++ b/tasks/ast_tools/src/generators/visit.rs @@ -74,7 +74,7 @@ fn generate_visit(is_mut: bool, schema: &Schema) -> TokenStream { //! //! See: //! * [visitor pattern](https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html) - //! * [rustc visitor](https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast/src/visit.rs) + //! * [rustc visitor](https://github.com/rust-lang/rust/blob/1.82.0/compiler/rustc_ast/src/visit.rs) //!@@line_break #![allow( diff --git a/tasks/common/src/test_file.rs b/tasks/common/src/test_file.rs index 410c8e9db14228..ec6b1fc69cc2a1 100644 --- a/tasks/common/src/test_file.rs +++ b/tasks/common/src/test_file.rs @@ -19,7 +19,7 @@ impl TestFiles { } } - /// These are kept in sync with <https://github.com/privatenumber/minification-benchmarks/tree/master> + /// These are kept in sync with <https://github.com/privatenumber/minification-benchmarks/tree/d8d54ceeb206d318fa288b152904adf715b076b2> /// for checking against minification size in `tasks/minsize/minsize.snap`. pub fn minifier() -> Self { Self { diff --git a/tasks/compat_data/README.md b/tasks/compat_data/README.md index d7c9bd9f64aaef..2aeb38fd63345e 100644 --- a/tasks/compat_data/README.md +++ b/tasks/compat_data/README.md @@ -2,7 +2,7 @@ Get engine compatibility Data from https://github.com/compat-table/compat-table/ -Code extracted from https://github.com/babel/babel/tree/main/packages/babel-compat-data +Code extracted from https://github.com/babel/babel/tree/v7.26.2/packages/babel-compat-data ## Adding a new feature diff --git a/tasks/compat_data/build.js b/tasks/compat_data/build.js index 0142ab262057f1..909355d6069a8c 100644 --- a/tasks/compat_data/build.js +++ b/tasks/compat_data/build.js @@ -1,5 +1,5 @@ -// https://github.com/babel/babel/blob/main/packages/babel-compat-data/scripts/build-data.js -// https://github.com/babel/babel/blob/main/packages/babel-compat-data/scripts/utils-build-data.js +// https://github.com/babel/babel/blob/v7.26.2/packages/babel-compat-data/scripts/build-data.js +// https://github.com/babel/babel/blob/v7.26.2/packages/babel-compat-data/scripts/utils-build-data.js const fs = require('node:fs'); const envs = require('./compat-table/environments'); diff --git a/tasks/compat_data/chromium-to-electron.js b/tasks/compat_data/chromium-to-electron.js index ed01aeda05d1bf..b0bc83b52b137d 100644 --- a/tasks/compat_data/chromium-to-electron.js +++ b/tasks/compat_data/chromium-to-electron.js @@ -1,4 +1,4 @@ -// https://github.com/babel/babel/blob/main/packages/babel-compat-data/scripts/chromium-to-electron.js +// https://github.com/babel/babel/blob/v7.26.2/packages/babel-compat-data/scripts/chromium-to-electron.js const chromiumVersions = require('./chromium-versions'); const chromiumVersionList = Object.keys(chromiumVersions); diff --git a/tasks/compat_data/chromium-versions.js b/tasks/compat_data/chromium-versions.js index c1e1ea0159e2dc..57c33200250dcc 100644 --- a/tasks/compat_data/chromium-versions.js +++ b/tasks/compat_data/chromium-versions.js @@ -1,4 +1,4 @@ -// https://github.com/Kilian/electron-to-chromium/blob/master/chromium-versions.js +// https://github.com/Kilian/electron-to-chromium/blob/v1.5.60/chromium-versions.js module.exports = { '39': '0.20', diff --git a/tasks/compat_data/es-features.js b/tasks/compat_data/es-features.js index 7e5414a62a271e..fd31390efc8ae0 100644 --- a/tasks/compat_data/es-features.js +++ b/tasks/compat_data/es-features.js @@ -1,5 +1,5 @@ -// https://github.com/babel/babel/blob/main/packages/babel-compat-data/scripts/data/plugin-features.js -// https://github.com/evanw/esbuild/blob/main/compat-table/src/index.ts +// https://github.com/babel/babel/blob/v7.26.2/packages/babel-compat-data/scripts/data/plugin-features.js +// https://github.com/evanw/esbuild/blob/v0.24.0/compat-table/src/index.ts const f = (es) => (item) => { item.es = es; diff --git a/tasks/coverage/misc/fail/oxc-2394.ts b/tasks/coverage/misc/fail/oxc-2394.ts index 5dad81f5f032ad..2d4f916044e6ec 100644 --- a/tasks/coverage/misc/fail/oxc-2394.ts +++ b/tasks/coverage/misc/fail/oxc-2394.ts @@ -1,4 +1,4 @@ -// copy from https://github.com/microsoft/TypeScript/blob/main/tests/cases/conformance/node/nodeModulesImportAttributesTypeModeDeclarationEmitErrors.ts#L72 +// copy from https://github.com/microsoft/TypeScript/blob/v5.6.3/tests/cases/conformance/node/nodeModulesImportAttributesTypeModeDeclarationEmitErrors.ts#L72 // @filename: /node_modules/pkg/import.d.ts export interface ImportInterface {} diff --git a/tasks/coverage/src/runtime/runtime.js b/tasks/coverage/src/runtime/runtime.js index 48622535147be1..7d371345b25a9e 100644 --- a/tasks/coverage/src/runtime/runtime.js +++ b/tasks/coverage/src/runtime/runtime.js @@ -1,4 +1,4 @@ -// https://github.com/evanw/esbuild/blob/main/scripts/test262.js +// https://github.com/evanw/esbuild/blob/v0.24.0/scripts/test262.js // import fs from 'node:fs'; import { createServer } from 'node:http'; diff --git a/tasks/coverage/src/suite.rs b/tasks/coverage/src/suite.rs index e14da73823565d..1887bdd466cfe6 100644 --- a/tasks/coverage/src/suite.rs +++ b/tasks/coverage/src/suite.rs @@ -286,7 +286,7 @@ pub trait Case: Sized + Sync + Send + UnwindSafe { /// Mark strict mode as always strict /// - /// See <https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode> + /// See <https://github.com/tc39/test262/blob/05c45a4c430ab6fee3e0c7f0d47d8a30d8876a6d/INTERPRETING.md#strict-mode> fn always_strict(&self) -> bool { false } diff --git a/tasks/coverage/src/test262/mod.rs b/tasks/coverage/src/test262/mod.rs index b9224db648b2a0..46bca3b1fda7d5 100644 --- a/tasks/coverage/src/test262/mod.rs +++ b/tasks/coverage/src/test262/mod.rs @@ -116,7 +116,7 @@ impl Case for Test262Case { // each test must be executed twice: once in ECMAScript's non-strict mode, and again in ECMAScript's strict mode. // To run in strict mode, the test contents must be modified prior to execution-- // a "use strict" directive must be inserted as the initial character sequence of the file - // https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode + // https://github.com/tc39/test262/blob/05c45a4c430ab6fee3e0c7f0d47d8a30d8876a6d/INTERPRETING.md#strict-mode fn run(&mut self) { let flags = &self.meta.flags; let source_type = SourceType::cjs(); diff --git a/tasks/coverage/src/typescript/transpile_runner.rs b/tasks/coverage/src/typescript/transpile_runner.rs index 1f292cb5897864..30118f019dc79a 100644 --- a/tasks/coverage/src/typescript/transpile_runner.rs +++ b/tasks/coverage/src/typescript/transpile_runner.rs @@ -1,4 +1,4 @@ -//! <https://github.com/microsoft/TypeScript/blob/main/src/testRunner/transpileRunner.ts> +//! <https://github.com/microsoft/TypeScript/blob/v5.6.3/src/testRunner/transpileRunner.ts> use std::path::{Path, PathBuf}; diff --git a/tasks/lint_rules/src/eslint-rules.cjs b/tasks/lint_rules/src/eslint-rules.cjs index 25030def8d4969..f34d57a5f0c4ab 100644 --- a/tasks/lint_rules/src/eslint-rules.cjs +++ b/tasks/lint_rules/src/eslint-rules.cjs @@ -9,59 +9,59 @@ const { Linter } = require('eslint'); // - rule.meta.docs.recommended // Some plugins have the recommended flag in rule itself, but some plugins have it in config. -// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/index.ts +// https://github.com/typescript-eslint/typescript-eslint/blob/v8.9.0/packages/eslint-plugin/src/index.ts const { rules: pluginTypeScriptAllRules, configs: pluginTypeScriptConfigs, } = require('@typescript-eslint/eslint-plugin'); -// https://github.com/eslint-community/eslint-plugin-n/blob/master/lib/index.js +// https://github.com/eslint-community/eslint-plugin-n/blob/v17.13.2/lib/index.js const { rules: pluginNAllRules } = require('eslint-plugin-n'); -// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/index.js +// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v56.0.0/index.js const { rules: pluginUnicornAllRules, configs: pluginUnicornConfigs, } = require('eslint-plugin-unicorn'); -// https://github.com/gajus/eslint-plugin-jsdoc/blob/main/src/index.js +// https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.5.0/src/index.js const { // @ts-expect-error: Module has no exported member rules: pluginJSDocAllRules, // @ts-expect-error: Module has no exported member configs: pluginJSDocConfigs, } = require('eslint-plugin-jsdoc'); -// https://github.com/import-js/eslint-plugin-import/blob/main/src/index.js +// https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/src/index.js const { rules: pluginImportAllRules, configs: pluginImportConfigs, } = require('eslint-plugin-import'); -// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js +// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.9.0/src/index.js const { rules: pluginJSXA11yAllRules, configs: pluginJSXA11yConfigs, } = require('eslint-plugin-jsx-a11y'); -// https://github.com/jest-community/eslint-plugin-jest/blob/main/src/index.ts +// https://github.com/jest-community/eslint-plugin-jest/blob/v28.9.0/src/index.ts const { rules: pluginJestAllRules, configs: pluginJestConfigs, } = require('eslint-plugin-jest'); -// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/index.js +// https://github.com/jsx-eslint/eslint-plugin-react/blob/v7.37.2/index.js const { rules: pluginReactAllRules } = require('eslint-plugin-react'); -// https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/index.js +// https://github.com/facebook/react/blob/v18.3.1/packages/eslint-plugin-react-hooks/src/index.js const { rules: pluginReactHooksAllRules, } = require('eslint-plugin-react-hooks'); -// https://github.com/cvazac/eslint-plugin-react-perf/blob/master/index.js +// https://github.com/cvazac/eslint-plugin-react-perf/blob/9bfa930661a23218f5460ebd39d35d76ccdb5724/index.js const { rules: pluginReactPerfAllRules, configs: pluginReactPerfConfigs, } = require('eslint-plugin-react-perf'); // https://github.com/vercel/next.js/blob/canary/packages/eslint-plugin-next/src/index.ts const { rules: pluginNextAllRules } = require('@next/eslint-plugin-next'); -// https://github.com/eslint-community/eslint-plugin-promise/blob/main/index.js +// https://github.com/eslint-community/eslint-plugin-promise/blob/v7.1.0/index.js const { rules: pluginPromiseRules, configs: pluginPromiseConfigs, } = require('eslint-plugin-promise'); -// https://github.com/veritem/eslint-plugin-vitest/blob/main/src/index.ts +// https://github.com/veritem/eslint-plugin-vitest/blob/v1.1.9/src/index.ts const { rules: pluginVitestRules, configs: pluginVitestConfigs, diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/refresh/react-refresh/README.md b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/refresh/react-refresh/README.md index 45183164a06002..8603a42506e20b 100644 --- a/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/refresh/react-refresh/README.md +++ b/tasks/transform_conformance/tests/babel-plugin-transform-react-jsx/test/fixtures/refresh/react-refresh/README.md @@ -1,3 +1,3 @@ -The tests of this directory are copied from the (react-refresh)[https://github.com/facebook/react/blob/main/packages/react-refresh/src/__tests__/ReactFreshBabelPlugin-test.js], and did some style, import order, and other minor changes to made them work with our transformer. +The tests of this directory are copied from the (react-refresh)[https://github.com/facebook/react/blob/v18.3.1/packages/react-refresh/src/__tests__/ReactFreshBabelPlugin-test.js], and did some style, import order, and other minor changes to made them work with our transformer. NOTE: This directory only add tests copied from the upstream, so that we can distinguish the source of the test \ No newline at end of file From 28d37e478dd820f77acc1c70b2fcd6ab57b01a86 Mon Sep 17 00:00:00 2001 From: dalaoshu <laipichan@qq.com> Date: Sun, 17 Nov 2024 00:30:56 +0800 Subject: [PATCH 25/27] chore(justfile): add `pnpm install` to init (#7297) Recently, due to some issues, I had to re-clone the oxc project multiple times. After running `just init`, I always had to run `pnpm install` separately. We could include `pnpm install` to init command to streamline the process. In addition, I propose to include `cargo-binstall` in the init command. I'm not sure if we should include the `submodules` command in the init command, as it is generally unnecessary for most users unless they are working on specific projects like the minifier. --- justfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/justfile b/justfile index 9419c85c696c2c..fe94849a8d3976 100755 --- a/justfile +++ b/justfile @@ -16,7 +16,10 @@ alias new-typescript-rule := new-ts-rule # or install via `cargo install cargo-binstall` # Initialize the project by installing all the necessary tools. init: + # Rust related init cargo binstall watchexec-cli cargo-insta typos-cli cargo-shear dprint -y + # Node.js related init + pnpm install # When ready, run the same CI commands ready: From d445e0f6121fed53a772fa9aec6ef6b96528bd53 Mon Sep 17 00:00:00 2001 From: Ryan Walker <ryan.matthew.walker@gmail.com> Date: Sat, 16 Nov 2024 12:07:52 -0800 Subject: [PATCH 26/27] feat(linter): implement `unicorn/consistent-existence-index-check` (#7262) [unicorn/consistent-existence-index-check](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-existence-index-check.md) for #684 --------- Co-authored-by: Cam McHenry <camchenry@users.noreply.github.com> --- crates/oxc_linter/src/rules.rs | 2 + .../consistent_existence_index_check.rs | 676 ++++++++++++++++++ .../consistent_existence_index_check.snap | 142 ++++ 3 files changed, 820 insertions(+) create mode 100644 crates/oxc_linter/src/rules/unicorn/consistent_existence_index_check.rs create mode 100644 crates/oxc_linter/src/snapshots/consistent_existence_index_check.snap diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 8714025070a8a2..381bce640d212d 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -282,6 +282,7 @@ mod react_perf { mod unicorn { pub mod catch_error_name; pub mod consistent_empty_array_spread; + pub mod consistent_existence_index_check; pub mod consistent_function_scoping; pub mod empty_brace_spaces; pub mod error_message; @@ -869,6 +870,7 @@ oxc_macros::declare_all_lint_rules! { typescript::triple_slash_reference, unicorn::catch_error_name, unicorn::consistent_empty_array_spread, + unicorn::consistent_existence_index_check, unicorn::consistent_function_scoping, unicorn::empty_brace_spaces, unicorn::error_message, diff --git a/crates/oxc_linter/src/rules/unicorn/consistent_existence_index_check.rs b/crates/oxc_linter/src/rules/unicorn/consistent_existence_index_check.rs new file mode 100644 index 00000000000000..f2bb4dbbde6da3 --- /dev/null +++ b/crates/oxc_linter/src/rules/unicorn/consistent_existence_index_check.rs @@ -0,0 +1,676 @@ +use oxc_ast::{ + ast::{BinaryOperator, Expression, UnaryOperator, VariableDeclarationKind}, + AstKind, +}; + +use oxc_diagnostics::OxcDiagnostic; +use oxc_macros::declare_oxc_lint; +use oxc_semantic::AstNode; +use oxc_span::{GetSpan, Span}; + +use crate::{context::LintContext, rule::Rule}; + +#[derive(Debug, Default, Clone)] +pub struct ConsistentExistenceIndexCheck; + +fn consistent_existence_index_check_diagnostic( + replacement: &GetReplacementOutput, + span: Span, +) -> OxcDiagnostic { + let existence_or_non_existence = + if replacement.replacement_value == "-1" { "non-existence" } else { "existence" }; + + let label = format!( + "Prefer `{replacement_operator} {replacement_value}` over `{original_operator} {original_value}` to check {existenceOrNonExistence}.", + replacement_operator = replacement.replacement_operator, + replacement_value = replacement.replacement_value, + original_operator = replacement.original_operator, + original_value = replacement.original_value, + existenceOrNonExistence = existence_or_non_existence, + ); + + OxcDiagnostic::warn(label).with_label(span) +} + +declare_oxc_lint!( + /// ### What it does + /// + /// Enforce consistent style for element existence checks with `indexOf()`, `lastIndexOf()`, `findIndex()`, and `findLastIndex()` + /// + /// ### Why is this bad? + /// + /// This rule is only meant to enforce a specific style and make comparisons more clear. + /// + /// ### Examples + /// + /// Examples of **incorrect** code for this rule: + /// + /// ```javascript + /// const index = foo.indexOf('bar'); + /// if (index < 0) {} + /// ``` + /// + /// ``` javascript + /// const index = foo.indexOf('bar'); + /// if (index >= 0) {} + /// ``` + /// + /// Examples of **correct** code for this rule: + /// + /// ```javascript + /// const index = foo.indexOf('bar'); + /// if (index === -1) {} + /// ``` + /// + /// ``` javascript + /// const index = foo.indexOf('bar'); + /// if (index !== -1) {} + /// ``` + ConsistentExistenceIndexCheck, + style, + fix, +); + +const METHOD_NAMES: [&str; 4] = ["indexOf", "lastIndexOf", "findIndex", "findLastIndex"]; + +impl Rule for ConsistentExistenceIndexCheck { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + let AstKind::BinaryExpression(binary_expression) = node.kind() else { + return; + }; + + let left = binary_expression.left.get_inner_expression(); + let right = binary_expression.right.get_inner_expression(); + let operator = binary_expression.operator; + + let Expression::Identifier(identifier) = left else { + return; + }; + + let Some(reference_id) = identifier.reference_id.get() else { + return; + }; + + let Some(reference_symbol_id) = ctx.symbols().get_reference(reference_id).symbol_id() + else { + return; + }; + + let declaration = ctx.symbols().get_declaration(reference_symbol_id); + let node = ctx.nodes().get_node(declaration); + + if let AstKind::VariableDeclarator(variables_declarator) = node.kind() { + if variables_declarator.kind != VariableDeclarationKind::Const { + return; + } + + let Some(Expression::CallExpression(call)) = &variables_declarator.init else { + return; + }; + + if !call.callee.is_member_expression() { + return; + } + + let Some(callee_name) = call.callee_name() else { + return; + }; + + if !METHOD_NAMES.contains(&callee_name) { + return; + } + + let replacement = get_replacement(right, operator); + + let Some(replacement) = &replacement else { + return; + }; + + ctx.diagnostic_with_fix( + consistent_existence_index_check_diagnostic(replacement, binary_expression.span), + |fixer| { + let operator_start = binary_expression.left.span().end; + let operator_end = binary_expression.right.span().start; + let operator_span = Span::new(operator_start, operator_end); + let operator_source = ctx.source_range(operator_span); + + let operator_matches = + operator_source.match_indices(replacement.original_operator); + let mut operator_replacement_text = operator_source.to_string(); + + for (index, text) in operator_matches { + let comments = ctx.semantic().comments_range(operator_start..operator_end); + + let start = operator_start + u32::try_from(index).unwrap_or(0); + let length = u32::try_from(text.len()).unwrap_or(0); + let span = Span::sized(start, length); + + let mut is_in_comment = false; + + for comment in comments { + if comment.span.contains_inclusive(span) { + is_in_comment = true; + break; + } + } + + if !is_in_comment { + let head = &operator_source[..index]; + let tail = &operator_source[index + text.len()..]; + + operator_replacement_text = + format!("{}{}{}", head, replacement.replacement_operator, tail); + } + } + + let fixer = fixer.for_multifix(); + let mut rule_fixes = fixer.new_fix_with_capacity(2); + + rule_fixes.push(fixer.replace(operator_span, operator_replacement_text)); + rule_fixes.push(fixer.replace(right.span(), replacement.replacement_value)); + + rule_fixes + }, + ); + }; + } +} + +#[derive(Debug, Clone)] +struct GetReplacementOutput { + pub replacement_operator: &'static str, + pub replacement_value: &'static str, + pub original_operator: &'static str, + pub original_value: &'static str, +} + +fn get_replacement(right: &Expression, operator: BinaryOperator) -> Option<GetReplacementOutput> { + match operator { + BinaryOperator::LessThan => { + if right.is_number_0() { + return Some(GetReplacementOutput { + replacement_operator: "===", + replacement_value: "-1", + original_operator: "<", + original_value: "0", + }); + } + + None + } + BinaryOperator::GreaterThan => { + if is_negative_one(right.get_inner_expression()) { + return Some(GetReplacementOutput { + replacement_operator: "!==", + replacement_value: "-1", + original_operator: ">", + original_value: "-1", + }); + } + + None + } + BinaryOperator::GreaterEqualThan => { + if right.is_number_0() { + return Some(GetReplacementOutput { + replacement_operator: "!==", + replacement_value: "-1", + original_operator: ">=", + original_value: "0", + }); + } + + None + } + _ => None, + } +} + +fn is_negative_one(expression: &Expression) -> bool { + if let Expression::UnaryExpression(unary_expression) = expression { + if let UnaryOperator::UnaryNegation = unary_expression.operator { + if let Expression::NumericLiteral(value) = + &unary_expression.argument.get_inner_expression() + { + return value.raw == "1"; + } + } + } + + false +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass: Vec<&str> = vec; index < 0;", + r"const index = foo.indexOf?.(foo); index < 0;", + r"const index = foo?.indexOf(foo); index < 0;", + ]; + + let fail = vec![ + r"const index = foo.indexOf('bar'); if (index < 0) {}", + r"const index = foo.lastIndexOf('bar'); if (index < 0) {}", + r"const index = foo.findIndex('bar'); if (index < 0) {}", + r"const index = foo.findLastIndex('bar'); if (index < 0) {}", + r"const index = foo.indexOf('bar'); if (index >= 0) {}", + r"const index = foo.lastIndexOf('bar'); if (index >= 0) {}", + r"const index = foo.findIndex('bar'); if (index >= 0) {}", + r"const index = foo.findLastIndex('bar'); if (index >= 0) {}", + r"const index = foo.indexOf('bar'); if (index > -1) {}", + r"const index = foo.lastIndexOf('bar'); if (index > -1) {}", + r"const index = foo.findIndex('bar'); if (index > -1) {}", + r"const index = foo.findLastIndex('bar'); if (index > -1) {}", + r" + const index = foo.indexOf(bar); + + function foo () { + if (index < 0) {} + } + ", + r" + const index1 = foo.indexOf('1'), + index2 = foo.indexOf('2'); + index1 < 0; + index2 >= 0; + ", + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + < + /* comment 5 */ + (( + /* comment 6 */ + 0 + /* comment 7 */ + )) + /* comment 8 */ + )); + ", + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + > + (( + /* comment 5 */ + - /* comment 6 */ (( /* comment 7 */ 1 /* comment 8 */ )) + /* comment 9 */ + )) + )); + ", + r"const index = _.indexOf([1, 2, 1, 2], 2); index < 0;", + ]; + + let fix = vec![ + ( + r"const index = foo.indexOf('bar'); if (index < 0) {}", + r"const index = foo.indexOf('bar'); if (index === -1) {}", + None, + ), + ( + r"const index = foo.lastIndexOf('bar'); if (index < 0) {}", + r"const index = foo.lastIndexOf('bar'); if (index === -1) {}", + None, + ), + ( + r"const index = foo.findIndex('bar'); if (index < 0) {}", + r"const index = foo.findIndex('bar'); if (index === -1) {}", + None, + ), + ( + r"const index = foo.findLastIndex('bar'); if (index < 0) {}", + r"const index = foo.findLastIndex('bar'); if (index === -1) {}", + None, + ), + ( + r"const index = foo.indexOf('bar'); if (index >= 0) {}", + r"const index = foo.indexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.lastIndexOf('bar'); if (index >= 0) {}", + r"const index = foo.lastIndexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findIndex('bar'); if (index >= 0) {}", + r"const index = foo.findIndex('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findLastIndex('bar'); if (index >= 0) {}", + r"const index = foo.findLastIndex('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.indexOf('bar'); if (index > -1) {}", + r"const index = foo.indexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.lastIndexOf('bar'); if (index > -1) {}", + r"const index = foo.lastIndexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findIndex('bar'); if (index > -1) {}", + r"const index = foo.findIndex('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findLastIndex('bar'); if (index > -1) {}", + r"const index = foo.findLastIndex('bar'); if (index !== -1) {}", + None, + ), + ( + r" + const index = foo.indexOf(bar); + + function foo () { + if (index < 0) {} + } + ", + r" + const index = foo.indexOf(bar); + + function foo () { + if (index === -1) {} + } + ", + None, + ), + ( + r" + const index1 = foo.indexOf('1'), + index2 = foo.indexOf('2'); + index1 < 0; + index2 >= 0; + ", + r" + const index1 = foo.indexOf('1'), + index2 = foo.indexOf('2'); + index1 === -1; + index2 !== -1; + ", + None, + ), + ( + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + < + /* comment 5 */ + (( + /* comment 6 */ + 0 + /* comment 7 */ + )) + /* comment 8 */ + )); + ", + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + === + /* comment 5 */ + (( + /* comment 6 */ + -1 + /* comment 7 */ + )) + /* comment 8 */ + )); + ", + None, + ), + ( + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + > + (( + /* comment 5 */ + - /* comment 6 */ (( /* comment 7 */ 1 /* comment 8 */ )) + /* comment 9 */ + )) + )); + ", + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 */ + !== + (( + /* comment 5 */ + -1 + /* comment 9 */ + )) + )); + ", + None, + ), + ( + r"const index = _.indexOf([1, 2, 1, 2], 2); index < 0;", + r"const index = _.indexOf([1, 2, 1, 2], 2); index === -1;", + None, + ), + ( + r"const i = foo.indexOf('bar'); if (i /* < */ < 0) {}", + r"const i = foo.indexOf('bar'); if (i /* < */ === -1) {}", + None, + ), + // make sure to not replace the wrong operator + ( + r" + const index = foo.indexOf('bar'); + if ( + index + /* >= */ + >= + 0 + ) {} + ", + r" + const index = foo.indexOf('bar'); + if ( + index + /* >= */ + !== + -1 + ) {} + ", + None, + ), + // make sure to not replace the wrong operator + ( + r" + const index = foo.indexOf('bar'); + if ( + index + /* >= */ + >= // >= + 0 + ) {} + ", + r" + const index = foo.indexOf('bar'); + if ( + index + /* >= */ + !== // >= + -1 + ) {} + ", + None, + ), + ( + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 < */ + < + /* comment 5 */ + (( + /* comment 6 */ + 0 + /* comment 7 */ + )) + /* comment 8 */ + )); + ", + r" + const index = foo.indexOf('1'); + (( + /* comment 1 */ + (( + /* comment 2 */ + index + /* comment 3 */ + )) + /* comment 4 < */ + === + /* comment 5 */ + (( + /* comment 6 */ + -1 + /* comment 7 */ + )) + /* comment 8 */ + )); + ", + None, + ), + ( + r"const index = foo.indexOf('bar'); if (index >= 0) {}", + r"const index = foo.indexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.lastIndexOf('bar'); if (index >= 0) {}", + r"const index = foo.lastIndexOf('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findIndex('bar'); if (index >= 0) {}", + r"const index = foo.findIndex('bar'); if (index !== -1) {}", + None, + ), + ( + r"const index = foo.findLastIndex('bar'); if (index >= 0) {}", + r"const index = foo.findLastIndex('bar'); if (index !== -1) {}", + None, + ), + ]; + + Tester::new(ConsistentExistenceIndexCheck::NAME, pass, fail) + .expect_fix(fix) + .test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/consistent_existence_index_check.snap b/crates/oxc_linter/src/snapshots/consistent_existence_index_check.snap new file mode 100644 index 00000000000000..4a8209eb75c2fa --- /dev/null +++ b/crates/oxc_linter/src/snapshots/consistent_existence_index_check.snap @@ -0,0 +1,142 @@ +--- +source: crates/oxc_linter/src/tester.rs +snapshot_kind: text +--- + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:39] + 1 │ const index = foo.indexOf('bar'); if (index < 0) {} + · ───────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:43] + 1 │ const index = foo.lastIndexOf('bar'); if (index < 0) {} + · ───────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:41] + 1 │ const index = foo.findIndex('bar'); if (index < 0) {} + · ───────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:45] + 1 │ const index = foo.findLastIndex('bar'); if (index < 0) {} + · ───────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `>= 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:39] + 1 │ const index = foo.indexOf('bar'); if (index >= 0) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `>= 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:43] + 1 │ const index = foo.lastIndexOf('bar'); if (index >= 0) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `>= 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:41] + 1 │ const index = foo.findIndex('bar'); if (index >= 0) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `>= 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:45] + 1 │ const index = foo.findLastIndex('bar'); if (index >= 0) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `> -1` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:39] + 1 │ const index = foo.indexOf('bar'); if (index > -1) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `> -1` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:43] + 1 │ const index = foo.lastIndexOf('bar'); if (index > -1) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `> -1` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:41] + 1 │ const index = foo.findIndex('bar'); if (index > -1) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `> -1` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:45] + 1 │ const index = foo.findLastIndex('bar'); if (index > -1) {} + · ────────── + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:5:15] + 4 │ function foo () { + 5 │ if (index < 0) {} + · ───────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:4:10] + 3 │ index2 = foo.indexOf('2'); + 4 │ index1 < 0; + · ────────── + 5 │ index2 >= 0; + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `>= 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:5:10] + 4 │ index1 < 0; + 5 │ index2 >= 0; + · ─────────── + 6 │ + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:5:17] + 4 │ /* comment 1 */ + 5 │ ╭─▶ (( + 6 │ │ /* comment 2 */ + 7 │ │ index + 8 │ │ /* comment 3 */ + 9 │ │ )) + 10 │ │ /* comment 4 */ + 11 │ │ < + 12 │ │ /* comment 5 */ + 13 │ │ (( + 14 │ │ /* comment 6 */ + 15 │ │ 0 + 16 │ │ /* comment 7 */ + 17 │ ╰─▶ )) + 18 │ /* comment 8 */ + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `!== -1` over `> -1` to check non-existence. + ╭─[consistent_existence_index_check.tsx:5:11] + 4 │ /* comment 1 */ + 5 │ ╭─▶ (( + 6 │ │ /* comment 2 */ + 7 │ │ index + 8 │ │ /* comment 3 */ + 9 │ │ )) + 10 │ │ /* comment 4 */ + 11 │ │ > + 12 │ │ (( + 13 │ │ /* comment 5 */ + 14 │ │ - /* comment 6 */ (( /* comment 7 */ 1 /* comment 8 */ )) + 15 │ │ /* comment 9 */ + 16 │ ╰─▶ )) + 17 │ )); + ╰──── + + ⚠ eslint-plugin-unicorn(consistent-existence-index-check): Prefer `=== -1` over `< 0` to check non-existence. + ╭─[consistent_existence_index_check.tsx:1:43] + 1 │ const index = _.indexOf([1, 2, 1, 2], 2); index < 0; + · ───────── + ╰──── From 7d75130865fe193435cf555e7bec20f0802818d0 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Sun, 17 Nov 2024 05:01:44 +0000 Subject: [PATCH 27/27] fix(transformer/async-to-generator): `arguments` isn't correct after transformation (#7234) Fix due to this plugin transforming the async method and async arrow function, it caused arguments no longer point the original function. For example: Before ```js class Cls { async method() { () => { console.log(arguments) } } } ``` After: ```js class Cls { method() { var _arguments = arguments; return babelHelpers.asyncToGenerator(function* () { () => { console.log(_arguments); }; })(); } } ``` In this way, the `_arguments` is its original function's arguments ### For performance regression It seems we need to check the IdentifierReference and BindingIdentifier if it's an `arguments`, that causes a significant regression, we may need a cheap way to do checking --- crates/oxc_semantic/src/reference.rs | 2 +- crates/oxc_semantic/src/scope.rs | 7 + crates/oxc_semantic/src/symbol.rs | 6 + .../src/common/arrow_function_converter.rs | 233 ++++++++++++++++-- crates/oxc_transformer/src/common/mod.rs | 16 ++ crates/oxc_transformer/src/lib.rs | 16 ++ .../snapshots/oxc.snap.md | 2 +- .../test/fixtures/arguments/assign/input.js | 4 + .../test/fixtures/arguments/assign/output.js | 9 + .../fixtures/arguments/async-method/input.js | 7 + .../fixtures/arguments/async-method/output.js | 10 + .../fixtures/arguments/nested-block/input.js | 7 + .../fixtures/arguments/nested-block/output.js | 12 + 13 files changed, 313 insertions(+), 18 deletions(-) create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/input.js create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/output.js create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/input.js create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/output.js create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/input.js create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/output.js diff --git a/crates/oxc_semantic/src/reference.rs b/crates/oxc_semantic/src/reference.rs index 4bf1ecc4e63e1c..544e17d8887fda 100644 --- a/crates/oxc_semantic/src/reference.rs +++ b/crates/oxc_semantic/src/reference.rs @@ -81,7 +81,7 @@ impl Reference { } #[inline] - pub(crate) fn set_symbol_id(&mut self, symbol_id: SymbolId) { + pub fn set_symbol_id(&mut self, symbol_id: SymbolId) { self.symbol_id = Some(symbol_id); } diff --git a/crates/oxc_semantic/src/scope.rs b/crates/oxc_semantic/src/scope.rs index df526f5bfaed1a..612e6c93150fc0 100644 --- a/crates/oxc_semantic/src/scope.rs +++ b/crates/oxc_semantic/src/scope.rs @@ -351,6 +351,13 @@ impl ScopeTree { } } + /// Rename a binding to a new name. + pub fn rename_binding(&mut self, scope_id: ScopeId, old_name: &str, new_name: CompactStr) { + if let Some(symbol_id) = self.bindings[scope_id].shift_remove(old_name) { + self.bindings[scope_id].insert(new_name, symbol_id); + } + } + /// Reserve memory for an `additional` number of scopes. pub fn reserve(&mut self, additional: usize) { self.parent_ids.reserve(additional); diff --git a/crates/oxc_semantic/src/symbol.rs b/crates/oxc_semantic/src/symbol.rs index 3c220cbc6e5a08..1527997e53ccf7 100644 --- a/crates/oxc_semantic/src/symbol.rs +++ b/crates/oxc_semantic/src/symbol.rs @@ -102,6 +102,12 @@ impl SymbolTable { &self.names[symbol_id] } + /// Rename a symbol. + #[inline] + pub fn rename(&mut self, symbol_id: SymbolId, new_name: CompactStr) { + self.names[symbol_id] = new_name; + } + #[inline] pub fn set_name(&mut self, symbol_id: SymbolId, name: CompactStr) { self.names[symbol_id] = name; diff --git a/crates/oxc_transformer/src/common/arrow_function_converter.rs b/crates/oxc_transformer/src/common/arrow_function_converter.rs index 9de158b3e68aff..acde13c691ff34 100644 --- a/crates/oxc_transformer/src/common/arrow_function_converter.rs +++ b/crates/oxc_transformer/src/common/arrow_function_converter.rs @@ -87,16 +87,18 @@ //! The Implementation based on //! <https://github.com/babel/babel/blob/d20b314c14533ab86351ecf6ca6b7296b66a57b3/packages/babel-traverse/src/path/conversion.ts#L170-L247> +use rustc_hash::{FxHashMap, FxHashSet}; + use oxc_allocator::{Box as ArenaBox, String as ArenaString, Vec as ArenaVec}; use oxc_ast::{ast::*, AstBuilder, NONE}; use oxc_data_structures::stack::SparseStack; -use oxc_span::SPAN; +use oxc_semantic::{ReferenceFlags, SymbolId}; +use oxc_span::{CompactStr, SPAN}; use oxc_syntax::{ scope::{ScopeFlags, ScopeId}, symbol::SymbolFlags, }; use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx}; -use rustc_hash::FxHashMap; use crate::EnvOptions; @@ -125,6 +127,8 @@ struct SuperMethodInfo<'a> { pub struct ArrowFunctionConverter<'a> { mode: ArrowFunctionConverterMode, this_var_stack: SparseStack<BoundIdentifier<'a>>, + arguments_var_stack: SparseStack<BoundIdentifier<'a>>, + renamed_arguments_symbol_ids: FxHashSet<SymbolId>, super_methods: Option<FxHashMap<Atom<'a>, SuperMethodInfo<'a>>>, } @@ -137,8 +141,14 @@ impl<'a> ArrowFunctionConverter<'a> { } else { ArrowFunctionConverterMode::Disabled }; - // `SparseStack` is created with 1 empty entry, for `Program` - Self { mode, this_var_stack: SparseStack::new(), super_methods: None } + // `SparseStack`s are created with 1 empty entry, for `Program` + Self { + mode, + this_var_stack: SparseStack::new(), + arguments_var_stack: SparseStack::new(), + renamed_arguments_symbol_ids: FxHashSet::default(), + super_methods: None, + } } } @@ -153,14 +163,19 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { } let this_var = self.this_var_stack.take_last(); + let arguments_var = self.arguments_var_stack.take_last(); self.insert_variable_statement_at_the_top_of_statements( program.scope_id(), &mut program.body, this_var, + arguments_var, ctx, ); + debug_assert!(self.this_var_stack.len() == 1); debug_assert!(self.this_var_stack.last().is_none()); + debug_assert!(self.arguments_var_stack.len() == 1); + debug_assert!(self.arguments_var_stack.last().is_none()); } fn enter_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) { @@ -169,6 +184,7 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { } self.this_var_stack.push(None); + self.arguments_var_stack.push(None); if self.is_async_only() && func.r#async && Self::is_class_method_like_ancestor(ctx.parent()) { self.super_methods = Some(FxHashMap::default()); @@ -196,10 +212,12 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { return; }; let this_var = self.this_var_stack.pop(); + let arguments_var = self.arguments_var_stack.pop(); self.insert_variable_statement_at_the_top_of_statements( scope_id, &mut body.statements, this_var, + arguments_var, ctx, ); } @@ -222,6 +240,8 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { block.scope_id(), &mut block.body, this_var, + // `arguments` is not allowed to be used in static blocks + None, ctx, ); } @@ -301,6 +321,22 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { *expr = Self::transform_arrow_function_expression(arrow_function_expr, ctx); } } + + fn enter_identifier_reference( + &mut self, + ident: &mut IdentifierReference<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.transform_identifier_reference_for_arguments(ident, ctx); + } + + fn enter_binding_identifier( + &mut self, + ident: &mut BindingIdentifier<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.transform_binding_identifier_for_arguments(ident, ctx); + } } impl<'a> ArrowFunctionConverter<'a> { @@ -787,28 +823,196 @@ impl<'a> ArrowFunctionConverter<'a> { ast.atom(name.into_bump_str()) } + /// Whether to transform the `arguments` identifier. + fn should_transform_arguments_identifier(&self, name: &str, ctx: &mut TraverseCtx<'a>) -> bool { + self.is_async_only() && name == "arguments" && Self::is_affected_arguments_identifier(ctx) + } + + /// Check if the `arguments` identifier is affected by the transformation. + fn is_affected_arguments_identifier(ctx: &mut TraverseCtx<'a>) -> bool { + let mut ancestors = ctx.ancestors().skip(1); + while let Some(ancestor) = ancestors.next() { + match ancestor { + Ancestor::ArrowFunctionExpressionParams(arrow) => { + if *arrow.r#async() { + return true; + } + } + Ancestor::ArrowFunctionExpressionBody(arrow) => { + if *arrow.r#async() { + return true; + } + } + Ancestor::FunctionBody(func) => { + return *func.r#async() + && Self::is_class_method_like_ancestor(ancestors.next().unwrap()); + } + _ => (), + } + } + + false + } + + /// Rename the `arguments` symbol to a new name. + fn rename_arguments_symbol(symbol_id: SymbolId, name: CompactStr, ctx: &mut TraverseCtx<'a>) { + let scope_id = ctx.symbols().get_scope_id(symbol_id); + ctx.symbols_mut().rename(symbol_id, name.clone()); + ctx.scopes_mut().rename_binding(scope_id, "arguments", name); + } + + /// Transform the identifier reference for `arguments` if it's affected after transformation. + /// + /// See [`Self::transform_member_expression_for_super`] for the reason. + fn transform_identifier_reference_for_arguments( + &mut self, + ident: &mut IdentifierReference<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + if !self.should_transform_arguments_identifier(&ident.name, ctx) { + return; + } + + let reference_id = ident.reference_id(); + let symbol_id = ctx.symbols().get_reference(reference_id).symbol_id(); + + let binding = self.arguments_var_stack.last_or_init(|| { + if let Some(symbol_id) = symbol_id { + let arguments_name = ctx.generate_uid_name("arguments"); + let arguments_name_atom = ctx.ast.atom(&arguments_name); + Self::rename_arguments_symbol(symbol_id, arguments_name, ctx); + // Record the symbol ID as a renamed `arguments` variable. + self.renamed_arguments_symbol_ids.insert(symbol_id); + BoundIdentifier::new(arguments_name_atom, symbol_id) + } else { + // We cannot determine the final scope ID of the `arguments` variable insertion, + // because the `arguments` variable will be inserted to a new scope which haven't been created yet, + // so we temporary use root scope id as the fake target scope ID. + let target_scope_id = ctx.scopes().root_scope_id(); + ctx.generate_uid("arguments", target_scope_id, SymbolFlags::FunctionScopedVariable) + } + }); + + // If no symbol ID, it means there is no variable named `arguments` in the scope. + // The following code is just to sync semantics. + if symbol_id.is_none() { + let reference = ctx.symbols_mut().get_reference_mut(reference_id); + reference.set_symbol_id(binding.symbol_id); + ctx.scopes_mut().delete_root_unresolved_reference(&ident.name, reference_id); + ctx.symbols_mut().resolved_references[binding.symbol_id].push(reference_id); + } + + ident.name = binding.name.clone(); + } + + /// Transform the binding identifier for `arguments` if it's affected after transformation. + /// + /// The main work is to rename the `arguments` binding identifier to a new name. + fn transform_binding_identifier_for_arguments( + &mut self, + ident: &mut BindingIdentifier<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + if ctx.current_scope_flags().is_strict_mode() // `arguments` is not allowed to be defined in strict mode. + || !self.should_transform_arguments_identifier(&ident.name, ctx) + { + return; + } + + self.arguments_var_stack.last_or_init(|| { + let arguments_name = ctx.generate_uid_name("arguments"); + ident.name = ctx.ast.atom(&arguments_name); + let symbol_id = ident.symbol_id(); + Self::rename_arguments_symbol(symbol_id, arguments_name, ctx); + // Record the symbol ID as a renamed `arguments` variable. + self.renamed_arguments_symbol_ids.insert(symbol_id); + BoundIdentifier::new(ident.name.clone(), symbol_id) + }); + } + + /// Create a variable declarator looks like `_arguments = arguments;`. + fn create_arguments_var_declarator( + &self, + target_scope_id: ScopeId, + arguments_var: Option<BoundIdentifier<'a>>, + ctx: &mut TraverseCtx<'a>, + ) -> Option<VariableDeclarator<'a>> { + let arguments_var = arguments_var?; + + // Just a renamed `arguments` variable, we don't need to create a new variable declaration. + if self.renamed_arguments_symbol_ids.contains(&arguments_var.symbol_id) { + return None; + } + + Self::adjust_binding_scope(target_scope_id, &arguments_var, ctx); + let reference = + ctx.create_unbound_ident_reference(SPAN, Atom::from("arguments"), ReferenceFlags::Read); + let mut init = Expression::Identifier(ctx.ast.alloc(reference.clone())); + + // Top level may doesn't have `arguments`, so we need to check it. + // `typeof arguments === "undefined" ? void 0 : arguments;` + if ctx.scopes().root_scope_id() == target_scope_id { + let argument = Expression::Identifier(ctx.ast.alloc(reference)); + let typeof_arguments = ctx.ast.expression_unary(SPAN, UnaryOperator::Typeof, argument); + let undefined_literal = ctx.ast.expression_string_literal(SPAN, "undefined"); + let test = ctx.ast.expression_binary( + SPAN, + typeof_arguments, + BinaryOperator::StrictEquality, + undefined_literal, + ); + init = ctx.ast.expression_conditional(SPAN, test, ctx.ast.void_0(SPAN), init); + } + + Some(ctx.ast.variable_declarator( + SPAN, + VariableDeclarationKind::Var, + arguments_var.create_binding_pattern(ctx), + Some(init), + false, + )) + } + /// Insert variable statement at the top of the statements. fn insert_variable_statement_at_the_top_of_statements( &mut self, target_scope_id: ScopeId, statements: &mut ArenaVec<'a, Statement<'a>>, this_var: Option<BoundIdentifier<'a>>, + arguments_var: Option<BoundIdentifier<'a>>, ctx: &mut TraverseCtx<'a>, ) { + // `_arguments = arguments;` + let arguments = self.create_arguments_var_declarator(target_scope_id, arguments_var, ctx); + + let is_class_method_like = Self::is_class_method_like_ancestor(ctx.parent()); + let declarations_count = usize::from(arguments.is_some()) + + if is_class_method_like { + self.super_methods.as_ref().map_or(0, FxHashMap::len) + } else { + 0 + } + + usize::from(this_var.is_some()); + + // Exit if no declarations to be inserted + if declarations_count == 0 { + return; + } + + let mut declarations = ctx.ast.vec_with_capacity(declarations_count); + + if let Some(arguments) = arguments { + declarations.push(arguments); + } + // `_superprop_getSomething = () => super.getSomething;` - let mut declarations = if Self::is_class_method_like_ancestor(ctx.parent()) { + if is_class_method_like { if let Some(super_methods) = self.super_methods.as_mut() { - let mut declarations = ctx.ast.vec_with_capacity(super_methods.len() + 1); declarations.extend(super_methods.drain().map(|(_, super_method)| { Self::generate_super_method(target_scope_id, super_method, ctx) })); - declarations - } else { - ctx.ast.vec_with_capacity(1) } - } else { - ctx.ast.vec_with_capacity(1) - }; + } // `_this = this;` if let Some(this_var) = this_var { @@ -823,10 +1027,7 @@ impl<'a> ArrowFunctionConverter<'a> { declarations.push(variable_declarator); } - // If there are no declarations, we don't need to insert a variable declaration. - if declarations.is_empty() { - return; - } + debug_assert_eq!(declarations_count, declarations.len()); let stmt = ctx.ast.alloc_variable_declaration( SPAN, diff --git a/crates/oxc_transformer/src/common/mod.rs b/crates/oxc_transformer/src/common/mod.rs index 8fc341179f10c8..6c372b4a52f19b 100644 --- a/crates/oxc_transformer/src/common/mod.rs +++ b/crates/oxc_transformer/src/common/mod.rs @@ -103,4 +103,20 @@ impl<'a, 'ctx> Traverse<'a> for Common<'a, 'ctx> { fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { self.arrow_function_converter.exit_expression(expr, ctx); } + + fn enter_binding_identifier( + &mut self, + node: &mut BindingIdentifier<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.arrow_function_converter.enter_binding_identifier(node, ctx); + } + + fn enter_identifier_reference( + &mut self, + node: &mut IdentifierReference<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.arrow_function_converter.enter_identifier_reference(node, ctx); + } } diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 474564f4339b0c..1ff1d32c6620e5 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -190,6 +190,22 @@ impl<'a, 'ctx> Traverse<'a> for TransformerImpl<'a, 'ctx> { self.x2_es2020.enter_big_int_literal(node, ctx); } + fn enter_binding_identifier( + &mut self, + node: &mut BindingIdentifier<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.common.enter_binding_identifier(node, ctx); + } + + fn enter_identifier_reference( + &mut self, + node: &mut IdentifierReference<'a>, + ctx: &mut TraverseCtx<'a>, + ) { + self.common.enter_identifier_reference(node, ctx); + } + fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, ctx: &mut TraverseCtx<'a>) { if let Some(typescript) = self.x0_typescript.as_mut() { typescript.enter_binding_pattern(pat, ctx); diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 1078e19e21a031..1cc7879ddaed13 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: d20b314c -Passed: 82/92 +Passed: 85/95 # All Passed: * babel-plugin-transform-class-static-block diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/input.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/input.js new file mode 100644 index 00000000000000..5b43966205ad82 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/input.js @@ -0,0 +1,4 @@ +const ArgumentsAssignment = async () => { + let arguments = arguments; + console.log(arguments); +}; diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/output.js new file mode 100644 index 00000000000000..097d15571fd88f --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/assign/output.js @@ -0,0 +1,9 @@ +const ArgumentsAssignment = /*#__PURE__*/function () { + var _ref = babelHelpers.asyncToGenerator(function* () { + let _arguments = _arguments; + console.log(_arguments); + }); + return function ArgumentsAssignment() { + return _ref.apply(this, arguments); + }; +}(); diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/input.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/input.js new file mode 100644 index 00000000000000..eb6b94e8fc8e34 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/input.js @@ -0,0 +1,7 @@ +class Cls { + async method() { + () => { + console.log(arguments); + } + } +} diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/output.js new file mode 100644 index 00000000000000..5650ed3766c7a1 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/async-method/output.js @@ -0,0 +1,10 @@ +class Cls { + method() { + var _arguments = arguments; + return babelHelpers.asyncToGenerator(function* () { + () => { + console.log(_arguments); + }; + })(); + } +} diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/input.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/input.js new file mode 100644 index 00000000000000..640d39129b23a6 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/input.js @@ -0,0 +1,7 @@ +const ArrowFunction = async () => { + { + var arguments = arguments; + console.log(arguments); + } + console.log(arguments); +}; diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/output.js new file mode 100644 index 00000000000000..1d962da7d59c91 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/arguments/nested-block/output.js @@ -0,0 +1,12 @@ +const ArrowFunction = /*#__PURE__*/function () { + var _ref = babelHelpers.asyncToGenerator(function* () { + { + var _arguments = _arguments; + console.log(_arguments); + } + console.log(_arguments); + }); + return function ArrowFunction() { + return _ref.apply(this, arguments); + }; +}();