diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 5bff5df99fc76..bf19b436867fe 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1284,12 +1284,14 @@ inherit_variants! { #[derive(Debug)] #[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, GetAddress, ContentEq, ESTree)] pub enum TSTypeQueryExprName<'a> { + /// `type foo = typeof import('foo')` TSImportType(Box<'a, TSImportType<'a>>) = 2, // `TSTypeName` variants added here by `inherit_variants!` macro @inherit TSTypeName } } +/// `type foo = import('foo')` #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, ContentEq, ESTree)] @@ -1299,9 +1301,6 @@ pub struct TSImportType<'a> { pub options: Option>>, pub qualifier: Option>, pub type_arguments: Option>>, - /// `true` for `typeof import("foo")` - #[estree(skip)] - pub is_type_of: bool, } /// TypeScript Function Type diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index 611e9c50f9115..768445f337105 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -1255,14 +1255,13 @@ const _: () = { assert!(size_of::() == 16); assert!(align_of::() == 8); - assert!(size_of::() == 64); + assert!(size_of::() == 56); assert!(align_of::() == 8); assert!(offset_of!(TSImportType, span) == 0); assert!(offset_of!(TSImportType, argument) == 8); assert!(offset_of!(TSImportType, options) == 24); assert!(offset_of!(TSImportType, qualifier) == 32); assert!(offset_of!(TSImportType, type_arguments) == 48); - assert!(offset_of!(TSImportType, is_type_of) == 56); assert!(size_of::() == 48); assert!(align_of::() == 8); @@ -2646,14 +2645,13 @@ const _: () = { assert!(size_of::() == 8); assert!(align_of::() == 4); - assert!(size_of::() == 36); + assert!(size_of::() == 32); assert!(align_of::() == 4); assert!(offset_of!(TSImportType, span) == 0); assert!(offset_of!(TSImportType, argument) == 8); assert!(offset_of!(TSImportType, options) == 16); assert!(offset_of!(TSImportType, qualifier) == 20); assert!(offset_of!(TSImportType, type_arguments) == 28); - assert!(offset_of!(TSImportType, is_type_of) == 32); assert!(size_of::() == 28); assert!(align_of::() == 4); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 2e18f43dc03dd..66d4787d9a712 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -10350,7 +10350,6 @@ impl<'a> AstBuilder<'a> { /// * `options` /// * `qualifier` /// * `type_arguments` - /// * `is_type_of`: `true` for `typeof import("foo")` #[inline] pub fn ts_type_import_type( self, @@ -10359,7 +10358,6 @@ impl<'a> AstBuilder<'a> { options: T1, qualifier: Option>, type_arguments: T2, - is_type_of: bool, ) -> TSType<'a> where T1: IntoIn<'a, Option>>>, @@ -10371,7 +10369,6 @@ impl<'a> AstBuilder<'a> { options, qualifier, type_arguments, - is_type_of, )) } @@ -13518,7 +13515,6 @@ impl<'a> AstBuilder<'a> { /// * `options` /// * `qualifier` /// * `type_arguments` - /// * `is_type_of`: `true` for `typeof import("foo")` #[inline] pub fn ts_type_query_expr_name_import_type( self, @@ -13527,7 +13523,6 @@ impl<'a> AstBuilder<'a> { options: T1, qualifier: Option>, type_arguments: T2, - is_type_of: bool, ) -> TSTypeQueryExprName<'a> where T1: IntoIn<'a, Option>>>, @@ -13539,7 +13534,6 @@ impl<'a> AstBuilder<'a> { options, qualifier, type_arguments, - is_type_of, )) } @@ -13554,7 +13548,6 @@ impl<'a> AstBuilder<'a> { /// * `options` /// * `qualifier` /// * `type_arguments` - /// * `is_type_of`: `true` for `typeof import("foo")` #[inline] pub fn ts_import_type( self, @@ -13563,7 +13556,6 @@ impl<'a> AstBuilder<'a> { options: T1, qualifier: Option>, type_arguments: T2, - is_type_of: bool, ) -> TSImportType<'a> where T1: IntoIn<'a, Option>>>, @@ -13575,7 +13567,6 @@ impl<'a> AstBuilder<'a> { options: options.into_in(self.allocator), qualifier, type_arguments: type_arguments.into_in(self.allocator), - is_type_of, } } @@ -13590,7 +13581,6 @@ impl<'a> AstBuilder<'a> { /// * `options` /// * `qualifier` /// * `type_arguments` - /// * `is_type_of`: `true` for `typeof import("foo")` #[inline] pub fn alloc_ts_import_type( self, @@ -13599,14 +13589,13 @@ impl<'a> AstBuilder<'a> { options: T1, qualifier: Option>, type_arguments: T2, - is_type_of: bool, ) -> Box<'a, TSImportType<'a>> where T1: IntoIn<'a, Option>>>, T2: IntoIn<'a, Option>>>, { Box::new_in( - self.ts_import_type(span, argument, options, qualifier, type_arguments, is_type_of), + self.ts_import_type(span, argument, options, qualifier, type_arguments), self.allocator, ) } diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs index 6e411ccbbeb35..845165b04172e 100644 --- a/crates/oxc_ast/src/generated/derive_clone_in.rs +++ b/crates/oxc_ast/src/generated/derive_clone_in.rs @@ -7385,7 +7385,6 @@ impl<'new_alloc> CloneIn<'new_alloc> for TSImportType<'_> { options: CloneIn::clone_in(&self.options, allocator), qualifier: CloneIn::clone_in(&self.qualifier, allocator), type_arguments: CloneIn::clone_in(&self.type_arguments, allocator), - is_type_of: CloneIn::clone_in(&self.is_type_of, allocator), } } @@ -7396,7 +7395,6 @@ impl<'new_alloc> CloneIn<'new_alloc> for TSImportType<'_> { options: CloneIn::clone_in_with_semantic_ids(&self.options, allocator), qualifier: CloneIn::clone_in_with_semantic_ids(&self.qualifier, allocator), type_arguments: CloneIn::clone_in_with_semantic_ids(&self.type_arguments, allocator), - is_type_of: CloneIn::clone_in_with_semantic_ids(&self.is_type_of, allocator), } } } diff --git a/crates/oxc_ast/src/generated/derive_content_eq.rs b/crates/oxc_ast/src/generated/derive_content_eq.rs index 56cfca8f0eed5..58d663134a7d8 100644 --- a/crates/oxc_ast/src/generated/derive_content_eq.rs +++ b/crates/oxc_ast/src/generated/derive_content_eq.rs @@ -2302,7 +2302,6 @@ impl ContentEq for TSImportType<'_> { && ContentEq::content_eq(&self.options, &other.options) && ContentEq::content_eq(&self.qualifier, &other.qualifier) && ContentEq::content_eq(&self.type_arguments, &other.type_arguments) - && ContentEq::content_eq(&self.is_type_of, &other.is_type_of) } } diff --git a/crates/oxc_ast/src/generated/derive_dummy.rs b/crates/oxc_ast/src/generated/derive_dummy.rs index 75d5052c0c681..e3b39eafa0288 100644 --- a/crates/oxc_ast/src/generated/derive_dummy.rs +++ b/crates/oxc_ast/src/generated/derive_dummy.rs @@ -2619,7 +2619,6 @@ impl<'a> Dummy<'a> for TSImportType<'a> { options: Dummy::dummy(allocator), qualifier: Dummy::dummy(allocator), type_arguments: Dummy::dummy(allocator), - is_type_of: Dummy::dummy(allocator), } } } diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index b0bcf83045071..9b2ad30e51a97 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -3527,9 +3527,6 @@ impl Gen for TSTypeQueryExprName<'_> { impl Gen for TSImportType<'_> { fn r#gen(&self, p: &mut Codegen, ctx: Context) { - if self.is_type_of { - p.print_str("typeof "); - } p.print_str("import("); self.argument.print(p, ctx); if let Some(options) = &self.options { diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index 98281b1d52a7a..cf81efff67429 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -390,11 +390,7 @@ impl<'a> ParserImpl<'a> { Ok(TSType::TSThisType(self.alloc(this_type))) } Kind::Typeof => { - if self.peek_at(Kind::Import) { - self.parse_ts_import_type() - } else { - self.parse_type_query() - } + self.parse_type_query() } Kind::LCurly => { if self.lookahead(Self::is_start_of_mapped_type) { @@ -405,7 +401,9 @@ impl<'a> ParserImpl<'a> { } Kind::LBrack => self.parse_tuple_type(), Kind::LParen => self.parse_parenthesized_type(), - Kind::Import => self.parse_ts_import_type(), + Kind::Import => self.parse_ts_import_type().map( + TSType::TSImportType + ), Kind::Asserts => { let peek_token = self.peek_token(); if peek_token.kind.is_identifier_name() && !peek_token.is_on_new_line { @@ -637,10 +635,19 @@ impl<'a> ParserImpl<'a> { fn parse_type_query(&mut self) -> Result> { let span = self.start_span(); self.bump_any(); // `bump `typeof` - let entity_name = self.parse_ts_type_name()?; // TODO: parseEntityName - let entity_name = TSTypeQueryExprName::from(entity_name); - let type_arguments = - if self.cur_token().is_on_new_line { None } else { self.try_parse_type_arguments()? }; + let (entity_name, type_arguments) = if self.at(Kind::Import) { + let entity_name = TSTypeQueryExprName::TSImportType(self.parse_ts_import_type()?); + (entity_name, None) + } else { + let entity_name = self.parse_ts_type_name()?; // TODO: parseEntityName + let entity_name = TSTypeQueryExprName::from(entity_name); + let type_arguments = if self.cur_token().is_on_new_line { + None + } else { + self.try_parse_type_arguments()? + }; + (entity_name, type_arguments) + }; Ok(self.ast.ts_type_type_query(self.end_span(span), entity_name, type_arguments)) } @@ -975,9 +982,8 @@ impl<'a> ParserImpl<'a> { Ok(self.ast.ts_type_literal_type(span, literal)) } - fn parse_ts_import_type(&mut self) -> Result> { + fn parse_ts_import_type(&mut self) -> Result>> { let span = self.start_span(); - let is_type_of = self.eat(Kind::Typeof); self.expect(Kind::Import)?; self.expect(Kind::LParen)?; let argument = self.parse_ts_type()?; @@ -986,13 +992,12 @@ impl<'a> ParserImpl<'a> { self.expect(Kind::RParen)?; let qualifier = if self.eat(Kind::Dot) { Some(self.parse_ts_type_name()?) } else { None }; let type_arguments = self.parse_type_arguments_of_type_reference()?; - Ok(self.ast.ts_type_import_type( + Ok(self.ast.alloc_ts_import_type( self.end_span(span), argument, options, qualifier, type_arguments, - is_type_of, )) } diff --git a/crates/oxc_traverse/src/generated/ancestor.rs b/crates/oxc_traverse/src/generated/ancestor.rs index 55c8564c15e98..ccc4d76a6cc88 100644 --- a/crates/oxc_traverse/src/generated/ancestor.rs +++ b/crates/oxc_traverse/src/generated/ancestor.rs @@ -14192,7 +14192,6 @@ pub(crate) const OFFSET_TS_IMPORT_TYPE_OPTIONS: usize = offset_of!(TSImportType, pub(crate) const OFFSET_TS_IMPORT_TYPE_QUALIFIER: usize = offset_of!(TSImportType, qualifier); pub(crate) const OFFSET_TS_IMPORT_TYPE_TYPE_ARGUMENTS: usize = offset_of!(TSImportType, type_arguments); -pub(crate) const OFFSET_TS_IMPORT_TYPE_IS_TYPE_OF: usize = offset_of!(TSImportType, is_type_of); #[repr(transparent)] #[derive(Clone, Copy, Debug)] @@ -14230,11 +14229,6 @@ impl<'a, 't> TSImportTypeWithoutArgument<'a, 't> { as *const Option>>) } } - - #[inline] - pub fn is_type_of(self) -> &'t bool { - unsafe { &*((self.0 as *const u8).add(OFFSET_TS_IMPORT_TYPE_IS_TYPE_OF) as *const bool) } - } } impl<'a, 't> GetAddress for TSImportTypeWithoutArgument<'a, 't> { @@ -14279,11 +14273,6 @@ impl<'a, 't> TSImportTypeWithoutOptions<'a, 't> { as *const Option>>) } } - - #[inline] - pub fn is_type_of(self) -> &'t bool { - unsafe { &*((self.0 as *const u8).add(OFFSET_TS_IMPORT_TYPE_IS_TYPE_OF) as *const bool) } - } } impl<'a, 't> GetAddress for TSImportTypeWithoutOptions<'a, 't> { @@ -14328,11 +14317,6 @@ impl<'a, 't> TSImportTypeWithoutQualifier<'a, 't> { as *const Option>>) } } - - #[inline] - pub fn is_type_of(self) -> &'t bool { - unsafe { &*((self.0 as *const u8).add(OFFSET_TS_IMPORT_TYPE_IS_TYPE_OF) as *const bool) } - } } impl<'a, 't> GetAddress for TSImportTypeWithoutQualifier<'a, 't> { @@ -14377,11 +14361,6 @@ impl<'a, 't> TSImportTypeWithoutTypeArguments<'a, 't> { as *const Option>) } } - - #[inline] - pub fn is_type_of(self) -> &'t bool { - unsafe { &*((self.0 as *const u8).add(OFFSET_TS_IMPORT_TYPE_IS_TYPE_OF) as *const bool) } - } } impl<'a, 't> GetAddress for TSImportTypeWithoutTypeArguments<'a, 't> { diff --git a/tasks/coverage/snapshots/estree_typescript.snap b/tasks/coverage/snapshots/estree_typescript.snap index 7cfe94bd20974..fcfa2c754fc12 100644 --- a/tasks/coverage/snapshots/estree_typescript.snap +++ b/tasks/coverage/snapshots/estree_typescript.snap @@ -2,7 +2,7 @@ commit: 15392346 estree_typescript Summary: AST Parsed : 10618/10725 (99.00%) -Positive Passed: 8062/10725 (75.17%) +Positive Passed: 8072/10725 (75.26%) Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/ClassDeclarationWithInvalidConstOnPropertyDeclaration.ts A class member cannot have the 'const' keyword. Mismatch: tasks/coverage/typescript/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -417,7 +417,6 @@ tasks/coverage/typescript/tests/cases/compiler/declarationEmitUsingAlternativeCo Unexpected estree file content error: 2 != 3 Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitUsingTypeAlias2.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitWithInvalidPackageJsonTypings.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationQuotedMembers.ts Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/declareAlreadySeen.ts declare' modifier already seen. @@ -1115,7 +1114,6 @@ tasks/coverage/typescript/tests/cases/compiler/moduleResolutionWithExtensions_wi Unexpected estree file content error: 3 != 5 Mismatch: tasks/coverage/typescript/tests/cases/compiler/moduleResolutionWithModule.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/moduleResolutionWithRequireAndImport.ts tasks/coverage/typescript/tests/cases/compiler/moduleResolutionWithSuffixes_one_externalModule.ts Unexpected estree file content error: 3 != 5 @@ -1543,10 +1541,7 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/typeVariableTypeGuards. Mismatch: tasks/coverage/typescript/tests/cases/compiler/typedArrays.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/typedArraysCrossAssignability01.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/typeofEnum.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/typeofImportInstantiationExpression.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/typeofThisInMethodSignature.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/umdGlobalAugmentationNoCrash.ts -Mismatch: tasks/coverage/typescript/tests/cases/compiler/umdNamespaceMergedWithGlobalAugmentationIsNotCircular.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/unaryPlus.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/undefinedAssignableToGenericMappedIntersection.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/underscoreEscapedNameInEnum.ts @@ -3267,14 +3262,9 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/conditional/in Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnType.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes02.tsx -Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeAmbient.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeAmdBundleRewrite.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeGenericTypes.ts tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeInJSDoc.ts Unexpected estree file content error: 1 != 2 -Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeLocal.ts -Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/import/importTypeLocalMissing.ts Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/types/import/importWithTypeArguments.ts Expected `from` but found `<` Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts