diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 6b4053715..7d460c2a3 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -113,6 +113,17 @@ pub enum Expression<'a> { } impl<'a> Expression<'a> { + pub fn is_typescript_syntax(&self) -> bool { + matches!( + self, + Self::TSAsExpression(_) + | Self::TSSatisfiesExpression(_) + | Self::TSTypeAssertion(_) + | Self::TSNonNullExpression(_) + | Self::TSInstantiationExpression(_) + ) + } + pub fn is_primary_expression(&self) -> bool { self.is_literal() || matches!( @@ -1289,6 +1300,7 @@ impl<'a> Declaration<'a> { _ => true, } } + pub fn modifiers(&self) -> Option<&Modifiers<'a>> { match self { Declaration::VariableDeclaration(decl) => Some(&decl.modifiers), @@ -1659,6 +1671,10 @@ impl<'a> BindingPattern<'a> { pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self { Self { kind, type_annotation: None, optional: false } } + + pub fn get_identifier(&self) -> Option<&Atom<'a>> { + self.kind.get_identifier() + } } #[derive(Debug, Hash)] @@ -1679,6 +1695,14 @@ pub enum BindingPatternKind<'a> { } impl<'a> BindingPatternKind<'a> { + pub fn get_identifier(&self) -> Option<&Atom<'a>> { + match self { + Self::BindingIdentifier(ident) => Some(&ident.name), + Self::AssignmentPattern(assign) => assign.left.get_identifier(), + _ => None, + } + } + pub fn is_destructuring_pattern(&self) -> bool { matches!(self, Self::ObjectPattern(_) | Self::ArrayPattern(_)) } @@ -1809,8 +1833,10 @@ pub struct Function<'a> { impl<'a> Function<'a> { pub fn is_typescript_syntax(&self) -> bool { - self.r#type == FunctionType::TSDeclareFunction - || self.body.is_none() + matches!( + self.r#type, + FunctionType::TSDeclareFunction | FunctionType::TSEmptyBodyFunctionExpression + ) || self.body.is_none() || self.modifiers.contains(ModifierKind::Declare) } diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 900769846..5e3d6cf41 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1007,6 +1007,12 @@ pub enum ModifierKind { Override, } +impl ModifierKind { + pub fn is_typescript_syntax(&self) -> bool { + !matches!(self, Self::Async | Self::Default | Self::Export | Self::Static) + } +} + #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1043,6 +1049,12 @@ impl<'a> Modifiers<'a> { pub fn is_contains_declare(&self) -> bool { self.contains(ModifierKind::Declare) } + + pub fn remove_type_modifiers(&mut self) { + if let Some(list) = &mut self.0 { + list.retain(|m| !m.kind.is_typescript_syntax()); + } + } } /// Export Assignment in non-module files diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index bd8e0f398..2f10c7fc8 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -51,6 +51,11 @@ impl<'a> AstBuilder<'a> { vec } + #[inline] + pub fn new_vec_from_iter>(&self, iter: I) -> Vec<'a, T> { + Vec::from_iter_in(iter, self.allocator) + } + #[inline] pub fn new_str(&self, value: &str) -> &'a str { String::from_str_in(value, self.allocator).into_bump_str() @@ -210,6 +215,14 @@ impl<'a> AstBuilder<'a> { Expression::TemplateLiteral(self.alloc(literal)) } + pub fn identifier_name(&self, span: Span, name: &str) -> IdentifierName<'a> { + IdentifierName::new(span, self.new_atom(name)) + } + + pub fn identifier_reference(&self, span: Span, name: &str) -> IdentifierReference<'a> { + IdentifierReference::new(span, self.new_atom(name)) + } + pub fn identifier_reference_expression( &self, ident: IdentifierReference<'a>, @@ -1195,6 +1208,22 @@ impl<'a> AstBuilder<'a> { }) } + pub fn plain_export_named_declaration( + &self, + span: Span, + specifiers: Vec<'a, ExportSpecifier<'a>>, + source: Option>, + ) -> Box<'a, ExportNamedDeclaration<'a>> { + self.export_named_declaration( + span, + None, + specifiers, + source, + ImportOrExportKind::Value, + None, + ) + } + /* ---------- JSX ----------------- */ pub fn jsx_element( &self, diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index adfa1151c..4858e194c 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -77,38 +77,135 @@ impl<'a> Transformer<'a> { } impl<'a> VisitMut<'a> for Transformer<'a> { - fn visit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { - self.x0_typescript.transform_statements(stmts); - walk_mut::walk_statements_mut(self, stmts); + fn visit_program(&mut self, program: &mut Program<'a>) { + walk_mut::walk_program_mut(self, program); + + self.x0_typescript.transform_program_on_exit(program); } - fn visit_statement(&mut self, stmt: &mut Statement<'a>) { - self.x2_decorators.transform_statement(stmt); - walk_mut::walk_statement_mut(self, stmt); + // ALPHASORT + + fn visit_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) { + self.x0_typescript.transform_arrow_expression(expr); + + walk_mut::walk_arrow_expression_mut(self, expr); } - fn visit_expression(&mut self, expr: &mut Expression<'a>) { - self.x1_react.transform_expression(expr); - walk_mut::walk_expression_mut(self, expr); + fn visit_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) { + self.x0_typescript.transform_binding_pattern(pat); + + walk_mut::walk_binding_pattern_mut(self, pat); } - fn visit_variable_declarator(&mut self, declarator: &mut VariableDeclarator<'a>) { - self.x1_react.transform_variable_declarator(declarator); - walk_mut::walk_variable_declarator_mut(self, declarator); + fn visit_call_expression(&mut self, expr: &mut CallExpression<'a>) { + self.x0_typescript.transform_call_expression(expr); + + walk_mut::walk_call_expression_mut(self, expr); } - fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) { - self.x1_react.transform_object_property(prop); - walk_mut::walk_object_property_mut(self, prop); + fn visit_class(&mut self, class: &mut Class<'a>) { + self.x0_typescript.transform_class(class); + + walk_mut::walk_class_mut(self, class); + } + + fn visit_class_body(&mut self, body: &mut ClassBody<'a>) { + self.x0_typescript.transform_class_body(body); + + walk_mut::walk_class_body_mut(self, body); } fn visit_export_default_declaration(&mut self, decl: &mut ExportDefaultDeclaration<'a>) { self.x1_react.transform_export_default_declaration(decl); + walk_mut::walk_export_default_declaration_mut(self, decl); } + fn visit_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) { + self.x0_typescript.transform_export_named_declaration(decl); + + walk_mut::walk_export_named_declaration_mut(self, decl); + } + + fn visit_expression(&mut self, expr: &mut Expression<'a>) { + self.x0_typescript.transform_expression(expr); + self.x1_react.transform_expression(expr); + + walk_mut::walk_expression_mut(self, expr); + } + + fn visit_formal_parameter(&mut self, param: &mut FormalParameter<'a>) { + self.x0_typescript.transform_formal_parameter(param); + + walk_mut::walk_formal_parameter_mut(self, param); + } + + fn visit_function(&mut self, func: &mut Function<'a>, flags: Option) { + self.x0_typescript.transform_function(func, flags); + + walk_mut::walk_function_mut(self, func, flags); + } + + fn visit_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) { + self.x0_typescript.transform_import_declaration(decl); + + walk_mut::walk_import_declaration_mut(self, decl); + } + fn visit_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { + self.x0_typescript.transform_jsx_opening_element(elem); self.x1_react.transform_jsx_opening_element(elem); + walk_mut::walk_jsx_opening_element_mut(self, elem); } + + fn visit_method_definition(&mut self, def: &mut MethodDefinition<'a>) { + self.x0_typescript.transform_method_definition(def); + + walk_mut::walk_method_definition_mut(self, def); + } + + fn visit_new_expression(&mut self, expr: &mut NewExpression<'a>) { + self.x0_typescript.transform_new_expression(expr); + + walk_mut::walk_new_expression_mut(self, expr); + } + + fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) { + self.x1_react.transform_object_property(prop); + + walk_mut::walk_object_property_mut(self, prop); + } + + fn visit_property_definition(&mut self, def: &mut PropertyDefinition<'a>) { + self.x0_typescript.transform_property_definition(def); + + walk_mut::walk_property_definition_mut(self, def); + } + + fn visit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { + self.x0_typescript.transform_statements(stmts); + + walk_mut::walk_statements_mut(self, stmts); + + self.x0_typescript.transform_statements_on_exit(stmts); + } + + fn visit_statement(&mut self, stmt: &mut Statement<'a>) { + self.x2_decorators.transform_statement(stmt); + + walk_mut::walk_statement_mut(self, stmt); + } + + fn visit_tagged_template_expression(&mut self, expr: &mut TaggedTemplateExpression<'a>) { + self.x0_typescript.transform_tagged_template_expression(expr); + + walk_mut::walk_tagged_template_expression_mut(self, expr); + } + + fn visit_variable_declarator(&mut self, declarator: &mut VariableDeclarator<'a>) { + self.x1_react.transform_variable_declarator(declarator); + + walk_mut::walk_variable_declarator_mut(self, declarator); + } } diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs new file mode 100644 index 000000000..2ed1b08cd --- /dev/null +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -0,0 +1,287 @@ +#![allow(clippy::unused_self)] + +use std::rc::Rc; + +use crate::context::Ctx; +use crate::TypeScriptOptions; + +use oxc_allocator::Vec; +use oxc_ast::ast::*; +use oxc_span::{Atom, SPAN}; +use oxc_syntax::operator::AssignmentOperator; +use rustc_hash::FxHashSet; + +pub struct TypeScriptAnnotations<'a> { + #[allow(dead_code)] + options: Rc, + ctx: Ctx<'a>, + + global_types: FxHashSet, +} + +impl<'a> TypeScriptAnnotations<'a> { + pub fn new(options: &Rc, ctx: &Ctx<'a>) -> Self { + Self { + options: Rc::clone(options), + ctx: Rc::clone(ctx), + global_types: FxHashSet::default(), + } + } + + pub fn is_global_type(&self) -> bool { + self.global_types.contains("TODO") + } + + // Convert `export = expr` into `module.exports = expr` + fn create_module_exports(&self, exp: &TSExportAssignment<'a>) -> Statement<'a> { + let ast = &self.ctx.ast; + + ast.expression_statement( + SPAN, + ast.assignment_expression( + SPAN, + AssignmentOperator::Assign, + ast.simple_assignment_target_member_expression(ast.static_member( + SPAN, + ast.identifier_reference_expression(ast.identifier_reference(SPAN, "module")), + ast.identifier_name(SPAN, "exports"), + false, + )), + ast.copy(&exp.expression), + ), + ) + } + + // Creates `this.name = name` + fn create_this_property_assignment(&self, name: &Atom<'a>) -> Statement<'a> { + let ast = &self.ctx.ast; + + ast.expression_statement( + SPAN, + ast.assignment_expression( + SPAN, + AssignmentOperator::Assign, + ast.simple_assignment_target_member_expression(ast.static_member( + SPAN, + ast.this_expression(SPAN), + ast.identifier_name(SPAN, name), + false, + )), + ast.identifier_reference_expression(ast.identifier_reference(SPAN, name)), + ), + ) + } + + // Remove type only imports/exports + pub fn transform_program_on_exit(&self, program: &mut Program<'a>) { + let mut module_count = 0; + + let body = + self.ctx.ast.move_statement_vec(&mut program.body).into_iter().filter_map(|stmt| { + // If an import/export declaration, remove all that are type-only + if let Statement::ModuleDeclaration(decl) = &stmt { + let keep = match &**decl { + ModuleDeclaration::ImportDeclaration(inner) => !inner.import_kind.is_type(), + ModuleDeclaration::ExportAllDeclaration(inner) => { + !inner.is_typescript_syntax() + } + ModuleDeclaration::ExportNamedDeclaration(inner) => { + !(inner.is_typescript_syntax() + || inner.specifiers.is_empty() + || inner.specifiers.iter().all(|spec| spec.export_kind.is_type()) + || self.is_global_type()) + } + ModuleDeclaration::ExportDefaultDeclaration(inner) => { + !inner.is_typescript_syntax() + } + ModuleDeclaration::TSNamespaceExportDeclaration(_) => false, + + // Replace with `module.exports = expr` + ModuleDeclaration::TSExportAssignment(exp) => { + return Some(self.create_module_exports(exp)); + } + }; + + if keep { + module_count += 1; + } else { + return None; + } + } + + Some(stmt) + }); + + program.body = self.ctx.ast.new_vec_from_iter(body); + + // Determine if we still have import/export statements, otherwise we + // need to inject an empty statement (`export {}`) so that the file is + // still considered a module + if module_count == 0 && self.ctx.semantic.source_type().is_module() { + // FIXME + // program.body.push(self.ctx.ast.module_declaration( + // ModuleDeclaration::ExportNamedDeclaration( + // self.ctx.ast.plain_export_named_declaration(SPAN, self.ctx.ast.new_vec(), None), + // ), + // )); + } + } + + pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) { + expr.type_parameters = None; + expr.return_type = None; + } + + pub fn transform_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) { + pat.type_annotation = None; + + if pat.kind.is_binding_identifier() { + pat.optional = false; + } + } + + pub fn transform_call_expression(&mut self, expr: &mut CallExpression<'a>) { + expr.type_parameters = None; + } + + pub fn transform_class(&mut self, class: &mut Class<'a>) { + class.type_parameters = None; + class.super_type_parameters = None; + class.implements = None; + class.modifiers.remove_type_modifiers(); + } + + pub fn transform_class_body(&mut self, body: &mut ClassBody<'a>) { + // Remove type only members + body.body.retain(|elem| match elem { + ClassElement::MethodDefinition(method) => { + matches!(method.r#type, MethodDefinitionType::MethodDefinition) + || !method.value.is_typescript_syntax() + } + ClassElement::PropertyDefinition(prop) => { + if prop.value.as_ref().is_some_and(Expression::is_typescript_syntax) + || prop.declare && prop.decorators.is_empty() + { + false + } else { + matches!(prop.r#type, PropertyDefinitionType::PropertyDefinition) + } + } + ClassElement::TSIndexSignature(_) => false, + _ => true, + }); + } + + pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) { + // Remove type only specifiers + decl.specifiers.retain(|spec| !spec.export_kind.is_type()); + } + + pub fn transform_expression(&mut self, expr: &mut Expression<'a>) { + *expr = self.ctx.ast.copy(expr.get_inner_expression()); + } + + pub fn transform_formal_parameter(&mut self, param: &mut FormalParameter<'a>) { + param.accessibility = None; + } + + pub fn transform_function( + &mut self, + func: &mut Function<'a>, + _flags: Option, + ) { + func.this_param = None; + func.type_parameters = None; + func.return_type = None; + func.modifiers.remove_type_modifiers(); + } + + pub fn transform_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) { + // Remove type only specifiers + if let Some(specifiers) = &mut decl.specifiers { + specifiers.retain(|spec| match spec { + ImportDeclarationSpecifier::ImportSpecifier(inner) => !inner.import_kind.is_type(), + _ => true, + }); + } + } + + pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { + elem.type_parameters = None; + } + + pub fn transform_method_definition(&mut self, def: &mut MethodDefinition<'a>) { + def.accessibility = None; + def.optional = false; + def.r#override = false; + + // Collects parameter properties so that we can add an assignment + // for each of them in the constructor body. + if def.kind == MethodDefinitionKind::Constructor { + let mut assigns = self.ctx.ast.new_vec(); + + for param in &def.value.params.items { + if param.pattern.type_annotation.is_none() { + continue; + } + + if let Some(id) = param.pattern.get_identifier() { + assigns.push(self.create_this_property_assignment(id)); + } + } + + if !assigns.is_empty() { + def.value + .body + .get_or_insert(self.ctx.ast.function_body( + SPAN, + self.ctx.ast.new_vec(), + self.ctx.ast.new_vec(), + )) + .statements + .extend(assigns); + } + } + } + + pub fn transform_new_expression(&mut self, expr: &mut NewExpression<'a>) { + expr.type_parameters = None; + } + + pub fn transform_property_definition(&mut self, def: &mut PropertyDefinition<'a>) { + assert!( + !(def.declare && def.value.is_some()), + "Fields with the 'declare' modifier cannot be initialized here, but only in the constructor" + ); + + assert!( + !(def.definite && def.value.is_some()), + "Definitely assigned fields cannot be initialized here, but only in the constructor" + ); + + def.accessibility = None; + def.declare = false; + def.definite = false; + def.r#override = false; + def.optional = false; + def.readonly = false; + def.type_annotation = None; + } + + pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { + // Remove TS specific statements + stmts.retain(|stmt| match stmt { + Statement::ExpressionStatement(s) => !s.expression.is_typescript_syntax(), + Statement::Declaration(s) => !s.is_typescript_syntax(), + // Ignore ModuleDeclaration as it's handled in the program + _ => true, + }); + } + + pub fn transform_tagged_template_expression( + &mut self, + expr: &mut TaggedTemplateExpression<'a>, + ) { + expr.type_parameters = None; + } +} diff --git a/crates/oxc_transformer/src/typescript/mod.rs b/crates/oxc_transformer/src/typescript/mod.rs index ca491c8ab..202b2595d 100644 --- a/crates/oxc_transformer/src/typescript/mod.rs +++ b/crates/oxc_transformer/src/typescript/mod.rs @@ -1,3 +1,4 @@ +mod annotations; mod namespace; use std::rc::Rc; @@ -9,6 +10,8 @@ use oxc_ast::ast::*; use crate::context::Ctx; +use self::annotations::TypeScriptAnnotations; + #[derive(Debug, Default, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TypeScriptOptions; @@ -36,19 +39,102 @@ pub struct TypeScriptOptions; /// Out: `const x = 0;` #[allow(unused)] pub struct TypeScript<'a> { - options: TypeScriptOptions, + options: Rc, ctx: Ctx<'a>, + + annotations: TypeScriptAnnotations<'a>, } impl<'a> TypeScript<'a> { pub fn new(options: TypeScriptOptions, ctx: &Ctx<'a>) -> Self { - Self { options, ctx: Rc::clone(ctx) } + let options = Rc::new(options); + + Self { + annotations: TypeScriptAnnotations::new(&options, ctx), + options, + ctx: Rc::clone(ctx), + } } } // Transforms impl<'a> TypeScript<'a> { + pub fn transform_program_on_exit(&self, program: &mut Program<'a>) { + self.annotations.transform_program_on_exit(program); + } + + pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) { + self.annotations.transform_arrow_expression(expr); + } + + pub fn transform_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) { + self.annotations.transform_binding_pattern(pat); + } + + pub fn transform_call_expression(&mut self, expr: &mut CallExpression<'a>) { + self.annotations.transform_call_expression(expr); + } + + pub fn transform_class(&mut self, class: &mut Class<'a>) { + self.annotations.transform_class(class); + } + + pub fn transform_class_body(&mut self, body: &mut ClassBody<'a>) { + self.annotations.transform_class_body(body); + } + + pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) { + self.annotations.transform_export_named_declaration(decl); + } + + pub fn transform_expression(&mut self, expr: &mut Expression<'a>) { + self.annotations.transform_expression(expr); + } + + pub fn transform_formal_parameter(&mut self, param: &mut FormalParameter<'a>) { + self.annotations.transform_formal_parameter(param); + } + + pub fn transform_function( + &mut self, + func: &mut Function<'a>, + flags: Option, + ) { + self.annotations.transform_function(func, flags); + } + + pub fn transform_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) { + self.annotations.transform_import_declaration(decl); + } + + pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { + self.annotations.transform_jsx_opening_element(elem); + } + + pub fn transform_method_definition(&mut self, def: &mut MethodDefinition<'a>) { + self.annotations.transform_method_definition(def); + } + + pub fn transform_new_expression(&mut self, expr: &mut NewExpression<'a>) { + self.annotations.transform_new_expression(expr); + } + + pub fn transform_property_definition(&mut self, def: &mut PropertyDefinition<'a>) { + self.annotations.transform_property_definition(def); + } + pub fn transform_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { self.transform_statements_for_namespace(stmts); } + + pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) { + self.annotations.transform_statements_on_exit(stmts); + } + + pub fn transform_tagged_template_expression( + &mut self, + expr: &mut TaggedTemplateExpression<'a>, + ) { + self.annotations.transform_tagged_template_expression(expr); + } } diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index 51a2f7a8d..1b4d9ed88 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -1,16 +1,15 @@ -Passed: 77/178 +Passed: 76/178 # All Passed: * babel-plugin-transform-react-jsx-source -# babel-plugin-transform-typescript (60/158) +# babel-plugin-transform-typescript (59/158) * class/abstract-class-decorated/input.ts * class/abstract-class-decorated-method/input.ts * class/abstract-class-decorated-parameter/input.ts * class/accessor-allowDeclareFields-false/input.ts * class/accessor-allowDeclareFields-true/input.ts -* class/declare/input.ts * class/decorated-declare-properties/input.ts * class/parameter-properties/input.ts * class/parameter-properties-late-super/input.ts @@ -23,6 +22,8 @@ Passed: 77/178 * declarations/erased/input.ts * declarations/export-declare-enum/input.ts * declarations/nested-namespace/input.mjs +* exports/declare-namespace/input.ts +* exports/declare-shadowed/input.ts * exports/declared-types/input.ts * exports/export-const-enums/input.ts * exports/export-type/input.ts @@ -33,9 +34,9 @@ Passed: 77/178 * exports/imported-types/input.ts * exports/imported-types-only-remove-type-imports/input.ts * exports/issue-9916-3/input.ts +* exports/simple/input.ts * exports/type-only-export-specifier-1/input.ts * exports/type-only-export-specifier-2/input.ts -* exports/type-only-export-specifier-3/input.ts * function/overloads-exports/input.mjs * imports/elide-injected/input.ts * imports/elide-preact/input.ts @@ -56,15 +57,12 @@ Passed: 77/178 * imports/import=-declaration/input.ts * imports/import=-module/input.ts * imports/import=-module-to-cjs/input.ts -* imports/only-remove-type-imports/input.ts * imports/parameter-decorators/input.ts * imports/property-signature/input.ts * imports/type-only-export-specifier-1/input.ts * imports/type-only-export-specifier-2/input.ts -* imports/type-only-import-specifier-1/input.ts * imports/type-only-import-specifier-2/input.ts * imports/type-only-import-specifier-3/input.ts -* imports/type-only-import-specifier-4/input.ts * namespace/alias/input.ts * namespace/ambient-module-nested/input.ts * namespace/ambient-module-nested-exported/input.ts @@ -74,7 +72,10 @@ Passed: 77/178 * namespace/clobber-export/input.ts * namespace/clobber-import/input.ts * namespace/contentious-names/input.ts +* namespace/declare/input.ts +* namespace/declare-global-nested-namespace/input.ts * namespace/empty-removed/input.ts +* namespace/export/input.ts * namespace/export-type-only/input.ts * namespace/module-nested/input.ts * namespace/module-nested-export/input.ts