diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 0a59c319876..7301ed7b7e1 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -5278,6 +5278,7 @@ func (c *Checker) checkImportDeclaration(node *ast.ImportDeclarationNode) { } if c.checkGrammarModuleElementContext(node, diagnostic) { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. + c.checkExternalModuleNameInGlobalScope(node) return } if !c.checkGrammarModifiers(node) && node.Modifiers() != nil { @@ -5468,6 +5469,7 @@ func (c *Checker) checkImportEqualsDeclaration(node *ast.Node) { diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module, diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module) if c.checkGrammarModuleElementContext(node, diagnostic) { + c.checkExternalModuleNameInGlobalScope(node) return // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. } c.checkGrammarModifiers(node) @@ -5510,6 +5512,7 @@ func (c *Checker) checkExportDeclaration(node *ast.ExportDeclarationNode) { diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module, diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module) if c.checkGrammarModuleElementContext(node, diagnostic) { + c.checkExternalModuleNameInGlobalScope(node) return // If we hit an export in an illegal context, just bail out to avoid cascading errors. } exportDecl := node.AsExportDeclaration() @@ -5553,6 +5556,15 @@ func (c *Checker) checkExportDeclaration(node *ast.ExportDeclarationNode) { c.checkImportAttributes(node) } +func (c *Checker) checkExternalModuleNameInGlobalScope(node *ast.Node) { + if getEnclosingContainer(node).Kind != ast.KindSourceFile || (ast.IsImportDeclarationOrJSImportDeclaration(node) && node.ImportClause() == nil) { + return + } + if moduleName := ast.GetExternalModuleName(node); moduleName != nil { + c.resolveExternalModuleName(node, moduleName, false) + } +} + func (c *Checker) checkExportSpecifier(node *ast.ExportSpecifierNode) { c.checkAliasSymbol(node) hasModuleSpecifier := node.Parent.Parent.ModuleSpecifier() != nil diff --git a/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.errors.txt b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.errors.txt new file mode 100644 index 00000000000..b89d3156232 --- /dev/null +++ b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.errors.txt @@ -0,0 +1,38 @@ +moduleDeclarationsInNonScopeBlock.ts(2,5): error TS1233: An export declaration can only be used at the top level of a namespace or module. +moduleDeclarationsInNonScopeBlock.ts(2,23): error TS2307: Cannot find module 'exportNamed' or its corresponding type declarations. +moduleDeclarationsInNonScopeBlock.ts(3,5): error TS1233: An export declaration can only be used at the top level of a namespace or module. +moduleDeclarationsInNonScopeBlock.ts(3,19): error TS2307: Cannot find module 'exportStar' or its corresponding type declarations. +moduleDeclarationsInNonScopeBlock.ts(4,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. +moduleDeclarationsInNonScopeBlock.ts(4,23): error TS2307: Cannot find module 'importNamed' or its corresponding type declarations. +moduleDeclarationsInNonScopeBlock.ts(5,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. +moduleDeclarationsInNonScopeBlock.ts(5,24): error TS2307: Cannot find module 'importEquals' or its corresponding type declarations. +moduleDeclarationsInNonScopeBlock.ts(6,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + + +==== moduleDeclarationsInNonScopeBlock.ts (9 errors) ==== + { + export { a } from "exportNamed"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used at the top level of a namespace or module. + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'exportNamed' or its corresponding type declarations. + export * from "exportStar"; + ~~~~~~ +!!! error TS1233: An export declaration can only be used at the top level of a namespace or module. + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'exportStar' or its corresponding type declarations. + import { b } from "importNamed"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used at the top level of a namespace or module. + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'importNamed' or its corresponding type declarations. + import c = require("importEquals"); + ~~~~~~ +!!! error TS1232: An import declaration can only be used at the top level of a namespace or module. + ~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'importEquals' or its corresponding type declarations. + import "sideEffect"; + ~~~~~~ +!!! error TS1232: An import declaration can only be used at the top level of a namespace or module. + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.js b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.js new file mode 100644 index 00000000000..c5072e7e789 --- /dev/null +++ b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts] //// + +//// [moduleDeclarationsInNonScopeBlock.ts] +{ + export { a } from "exportNamed"; + export * from "exportStar"; + import { b } from "importNamed"; + import c = require("importEquals"); + import "sideEffect"; +} + + +//// [moduleDeclarationsInNonScopeBlock.js] +"use strict"; +{ + export { a } from "exportNamed"; + export * from "exportStar"; + import { b } from "importNamed"; + import c = require("importEquals"); + import "sideEffect"; +} diff --git a/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.symbols b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.symbols new file mode 100644 index 00000000000..240e3397d6c --- /dev/null +++ b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts] //// + +=== moduleDeclarationsInNonScopeBlock.ts === +{ + export { a } from "exportNamed"; +>a : Symbol(a, Decl(moduleDeclarationsInNonScopeBlock.ts, 1, 12)) + + export * from "exportStar"; + import { b } from "importNamed"; +>b : Symbol(b, Decl(moduleDeclarationsInNonScopeBlock.ts, 3, 12)) + + import c = require("importEquals"); +>c : Symbol(c, Decl(moduleDeclarationsInNonScopeBlock.ts, 3, 36)) + + import "sideEffect"; +} + diff --git a/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.types b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.types new file mode 100644 index 00000000000..9e865e58cf2 --- /dev/null +++ b/testdata/baselines/reference/compiler/moduleDeclarationsInNonScopeBlock.types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts] //// + +=== moduleDeclarationsInNonScopeBlock.ts === +{ + export { a } from "exportNamed"; +>a : any + + export * from "exportStar"; + import { b } from "importNamed"; +>b : any + + import c = require("importEquals"); +>c : any + + import "sideEffect"; +} + diff --git a/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt b/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt index af0204ba8e2..9ebc0a62740 100644 --- a/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt +++ b/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt @@ -11,13 +11,14 @@ moduleElementsInWrongContext.ts(21,5): error TS1184: Modifiers cannot appear her moduleElementsInWrongContext.ts(22,5): error TS1184: Modifiers cannot appear here. moduleElementsInWrongContext.ts(23,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. moduleElementsInWrongContext.ts(24,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. +moduleElementsInWrongContext.ts(24,25): error TS2307: Cannot find module 'foo' or its corresponding type declarations. moduleElementsInWrongContext.ts(25,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. moduleElementsInWrongContext.ts(26,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. moduleElementsInWrongContext.ts(27,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. moduleElementsInWrongContext.ts(28,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. -==== moduleElementsInWrongContext.ts (17 errors) ==== +==== moduleElementsInWrongContext.ts (18 errors) ==== { namespace M { } ~~~~~~~~~ @@ -68,6 +69,8 @@ moduleElementsInWrongContext.ts(28,5): error TS1232: An import declaration can o import I2 = require("foo"); ~~~~~~ !!! error TS1232: An import declaration can only be used at the top level of a namespace or module. + ~~~~~ +!!! error TS2307: Cannot find module 'foo' or its corresponding type declarations. import * as Foo from "ambient"; ~~~~~~ !!! error TS1232: An import declaration can only be used at the top level of a namespace or module. diff --git a/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt.diff new file mode 100644 index 00000000000..af75aef53ba --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/moduleElementsInWrongContext.errors.txt.diff @@ -0,0 +1,27 @@ +--- old.moduleElementsInWrongContext.errors.txt ++++ new.moduleElementsInWrongContext.errors.txt +@@= skipped -10, +10 lines =@@ + moduleElementsInWrongContext.ts(22,5): error TS1184: Modifiers cannot appear here. + moduleElementsInWrongContext.ts(23,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + moduleElementsInWrongContext.ts(24,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. ++moduleElementsInWrongContext.ts(24,25): error TS2307: Cannot find module 'foo' or its corresponding type declarations. + moduleElementsInWrongContext.ts(25,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + moduleElementsInWrongContext.ts(26,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + moduleElementsInWrongContext.ts(27,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + moduleElementsInWrongContext.ts(28,5): error TS1232: An import declaration can only be used at the top level of a namespace or module. + + +-==== moduleElementsInWrongContext.ts (17 errors) ==== ++==== moduleElementsInWrongContext.ts (18 errors) ==== + { + namespace M { } + ~~~~~~~~~ +@@= skipped -57, +58 lines =@@ + import I2 = require("foo"); + ~~~~~~ + !!! error TS1232: An import declaration can only be used at the top level of a namespace or module. ++ ~~~~~ ++!!! error TS2307: Cannot find module 'foo' or its corresponding type declarations. + import * as Foo from "ambient"; + ~~~~~~ + !!! error TS1232: An import declaration can only be used at the top level of a namespace or module. \ No newline at end of file diff --git a/testdata/tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts b/testdata/tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts new file mode 100644 index 00000000000..345e899fe27 --- /dev/null +++ b/testdata/tests/cases/compiler/moduleDeclarationsInNonScopeBlock.ts @@ -0,0 +1,7 @@ +{ + export { a } from "exportNamed"; + export * from "exportStar"; + import { b } from "importNamed"; + import c = require("importEquals"); + import "sideEffect"; +}