diff --git a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs index 43ef8229bcbc..7737e510d353 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs @@ -112,6 +112,16 @@ fn test() { ), ("var App; var React; enum A { App }; React.render();", None), ("var React; enum A { App }; var App; React.render();", None), + ("var React; import App = require('./app'); React.render();", None), + ( + " + var React; + import { Foo } from './foo'; + import App = Foo.App; + React.render(); + ", + None, + ), ]; let fail = vec![ diff --git a/crates/oxc_semantic/src/binder.rs b/crates/oxc_semantic/src/binder.rs index e19ab2117655..ce14e8a08a68 100644 --- a/crates/oxc_semantic/src/binder.rs +++ b/crates/oxc_semantic/src/binder.rs @@ -294,6 +294,12 @@ impl<'a> Binder for ImportNamespaceSpecifier<'a> { } } +impl<'a> Binder for TSImportEqualsDeclaration<'a> { + fn bind(&self, builder: &mut SemanticBuilder) { + declare_symbol_for_import_specifier(&self.id, builder); + } +} + impl<'a> Binder for TSTypeAliasDeclaration<'a> { fn bind(&self, builder: &mut SemanticBuilder) { let symbol_id = builder.declare_symbol( diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 357963f40ae7..13e2137a140d 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -1672,6 +1672,9 @@ impl<'a> SemanticBuilder<'a> { AstKind::ImportNamespaceSpecifier(specifier) => { specifier.bind(self); } + AstKind::TSImportEqualsDeclaration(decl) => { + decl.bind(self); + } AstKind::VariableDeclarator(decl) => { decl.bind(self); self.make_all_namespaces_valuelike(); diff --git a/crates/oxc_semantic/tests/integration/modules.rs b/crates/oxc_semantic/tests/integration/modules.rs index 1fed48fcff2b..98b6f8cd51cc 100644 --- a/crates/oxc_semantic/tests/integration/modules.rs +++ b/crates/oxc_semantic/tests/integration/modules.rs @@ -202,3 +202,16 @@ fn test_export_in_invalid_scope() { assert!(!errors.is_empty(), "expected an export within a function to produce a check error, but no errors were produced"); assert!(semantic.module_record().exported_bindings.is_empty()); } + +#[test] +fn test_import_assignment() { + SemanticTester::ts("import Foo = require('./foo')") + .has_root_symbol("Foo") + .contains_flags(SymbolFlags::ImportBinding) + .test(); + + SemanticTester::ts("import { Foo } from './foo'; import Baz = Foo.Bar.Baz") + .has_root_symbol("Baz") + .contains_flags(SymbolFlags::ImportBinding) + .test(); +} diff --git a/tasks/coverage/parser_typescript.snap b/tasks/coverage/parser_typescript.snap index a6e2a90b9fcc..f65c08aec20e 100644 --- a/tasks/coverage/parser_typescript.snap +++ b/tasks/coverage/parser_typescript.snap @@ -3,7 +3,7 @@ commit: d8086f14 parser_typescript Summary: AST Parsed : 5279/5283 (99.92%) Positive Passed: 5272/5283 (99.79%) -Negative Passed: 1082/4875 (22.19%) +Negative Passed: 1085/4875 (22.26%) Expect Syntax Error: "compiler/ClassDeclaration10.ts" Expect Syntax Error: "compiler/ClassDeclaration11.ts" Expect Syntax Error: "compiler/ClassDeclaration13.ts" @@ -874,7 +874,6 @@ Expect Syntax Error: "compiler/implicitAnyWidenToAny.ts" Expect Syntax Error: "compiler/implicitConstParameters.ts" Expect Syntax Error: "compiler/importAnImport.ts" Expect Syntax Error: "compiler/importAndVariableDeclarationConflict1.ts" -Expect Syntax Error: "compiler/importAndVariableDeclarationConflict3.ts" Expect Syntax Error: "compiler/importAndVariableDeclarationConflict4.ts" Expect Syntax Error: "compiler/importDeclRefereingExternalModuleWithNoResolve.ts" Expect Syntax Error: "compiler/importDeclWithClassModifiers.ts" @@ -1186,8 +1185,6 @@ Expect Syntax Error: "compiler/moduleImport.ts" Expect Syntax Error: "compiler/moduleNewExportBug.ts" Expect Syntax Error: "compiler/moduleNoneErrors.ts" Expect Syntax Error: "compiler/moduleProperty2.ts" -Expect Syntax Error: "compiler/moduleSharesNameWithImportDeclarationInsideIt3.ts" -Expect Syntax Error: "compiler/moduleSharesNameWithImportDeclarationInsideIt5.ts" Expect Syntax Error: "compiler/moduleVariableArrayIndexer.ts" Expect Syntax Error: "compiler/moduleVisibilityTest2.ts" Expect Syntax Error: "compiler/moduleVisibilityTest3.ts" @@ -6866,6 +6863,17 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 17 │ } ╰──── + × Identifier `x` has already been declared + ╭─[compiler/importAndVariableDeclarationConflict3.ts:5:8] + 4 │ + 5 │ import x = m.m; + · ┬ + · ╰── `x` has already been declared here + 6 │ import x = m.m; + · ┬ + · ╰── It can not be redeclared here + ╰──── + × Unexpected token ╭─[compiler/importAssertionNonstring.ts:1:52] 1 │ import * as thing1 from "./mod.mjs" assert {field: 0}; @@ -7962,6 +7970,30 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── help: Try insert a semicolon here + × Identifier `M` has already been declared + ╭─[compiler/moduleSharesNameWithImportDeclarationInsideIt3.ts:10:12] + 9 │ module A.M { + 10 │ import M = Z.M; + · ┬ + · ╰── `M` has already been declared here + 11 │ import M = Z.I; + · ┬ + · ╰── It can not be redeclared here + 12 │ + ╰──── + + × Identifier `M` has already been declared + ╭─[compiler/moduleSharesNameWithImportDeclarationInsideIt5.ts:10:12] + 9 │ module A.M { + 10 │ import M = Z.I; + · ┬ + · ╰── `M` has already been declared here + 11 │ import M = Z.M; + · ┬ + · ╰── It can not be redeclared here + 12 │ + ╰──── + × TS1108: A 'return' statement can only be used within a function body ╭─[compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts:1:1] 1 │ return this.edit(role)