diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 304e77271a799..a7cb0d1275813 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1764,8 +1764,8 @@ namespace ts { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - case SyntaxKind.GlobalModuleExportDeclaration: - return bindGlobalModuleExportDeclaration(node); + case SyntaxKind.NamespaceExportDeclaration: + return bindNamespaceExportDeclaration(node); case SyntaxKind.ImportClause: return bindImportClause(node); case SyntaxKind.ExportDeclaration: @@ -1815,7 +1815,7 @@ namespace ts { } } - function bindGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { + function bindNamespaceExportDeclaration(node: NamespaceExportDeclaration) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Modifiers_cannot_appear_here)); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09da3858d31e8..489abd1ae51af 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -639,6 +639,7 @@ namespace ts { let propertyWithInvalidInitializer: Node; const errorLocation = location; let grandparent: Node; + let isInExternalModule = false; loop: while (location) { // Locals of a source file are not in scope (because they get merged into the global symbol table) @@ -686,6 +687,7 @@ namespace ts { switch (location.kind) { case SyntaxKind.SourceFile: if (!isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case SyntaxKind.ModuleDeclaration: const moduleExports = getSymbolOfNode(location).exports; if (location.kind === SyntaxKind.SourceFile || isAmbientModule(location)) { @@ -879,6 +881,14 @@ namespace ts { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + + // If we're in an external module, we can't reference symbols created from UMD export declarations + if (result && isInExternalModule) { + const decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) { + error(errorLocation, Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -1076,7 +1086,7 @@ namespace ts { return getExternalModuleMember(node.parent.parent.parent, node); } - function getTargetOfGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration): Symbol { + function getTargetOfGlobalModuleExportDeclaration(node: NamespaceExportDeclaration): Symbol { return resolveExternalModuleSymbol(node.parent.symbol); } @@ -1104,8 +1114,8 @@ namespace ts { return getTargetOfExportSpecifier(node); case SyntaxKind.ExportAssignment: return getTargetOfExportAssignment(node); - case SyntaxKind.GlobalModuleExportDeclaration: - return getTargetOfGlobalModuleExportDeclaration(node); + case SyntaxKind.NamespaceExportDeclaration: + return getTargetOfGlobalModuleExportDeclaration(node); } } @@ -6374,7 +6384,7 @@ namespace ts { if (kind === SignatureKind.Construct && sourceSignatures.length && targetSignatures.length) { if (isAbstractConstructorType(source) && !isAbstractConstructorType(target)) { // An abstract constructor type is not assignable to a non-abstract constructor type - // as it would otherwise be possible to new an abstract class. Note that the assignability + // as it would otherwise be possible to new an abstract class. Note that the assignability // check we perform for an extends clause excludes construct signatures from the target, // so this check never proceeds. if (reportErrors) { @@ -12878,7 +12888,7 @@ namespace ts { if (checkIfTypePredicateVariableIsDeclaredInBindingPattern( name, predicateVariableNode, - predicateVariableName)) { + predicateVariableName)) { return true; } } @@ -17497,7 +17507,7 @@ namespace ts { if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9942a71df3bba..747192d105b1e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1923,6 +1923,10 @@ "category": "Error", "code": 2685 }, + "Identifier '{0}' must be imported from a module": { + "category": "Error", + "code": 2686 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b60082969db6f..2672efb647c9a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -303,8 +303,8 @@ namespace ts { case SyntaxKind.ImportClause: return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).namedBindings); - case SyntaxKind.GlobalModuleExportDeclaration: - return visitNode(cbNode, (node).name); + case SyntaxKind.NamespaceExportDeclaration: + return visitNode(cbNode, (node).name); case SyntaxKind.NamespaceImport: return visitNode(cbNode, (node).name); @@ -5344,8 +5344,8 @@ namespace ts { return nextToken() === SyntaxKind.SlashToken; } - function parseGlobalModuleExportDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): GlobalModuleExportDeclaration { - const exportDeclaration = createNode(SyntaxKind.GlobalModuleExportDeclaration, fullStart); + function parseGlobalModuleExportDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): NamespaceExportDeclaration { + const exportDeclaration = createNode(SyntaxKind.NamespaceExportDeclaration, fullStart); exportDeclaration.decorators = decorators; exportDeclaration.modifiers = modifiers; parseExpected(SyntaxKind.AsKeyword); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6b2a5c0def484..8356e1fcd8763 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1762,10 +1762,6 @@ namespace ts { reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd); } - if (file) { - file.wasReferenced = file.wasReferenced || isReference; - } - return file; } @@ -1782,7 +1778,6 @@ namespace ts { filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 689812ed4194e..563b4fea7b8d6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -277,7 +277,7 @@ namespace ts { ModuleDeclaration, ModuleBlock, CaseBlock, - GlobalModuleExportDeclaration, + NamespaceExportDeclaration, ImportEqualsDeclaration, ImportDeclaration, ImportClause, @@ -1341,8 +1341,8 @@ namespace ts { name: Identifier; } - // @kind(SyntaxKind.GlobalModuleImport) - export interface GlobalModuleExportDeclaration extends DeclarationStatement { + // @kind(SyntaxKind.NamespaceExportDeclaration) + export interface NamespaceExportDeclaration extends DeclarationStatement { name: Identifier; moduleReference: LiteralLikeNode; } @@ -1599,8 +1599,6 @@ namespace ts { /* @internal */ externalModuleIndicator: Node; // The first node that causes this file to be a CommonJS module /* @internal */ commonJsModuleIndicator: Node; - // True if the file was a root file in a compilation or a /// reference targets - /* @internal */ wasReferenced?: boolean; /* @internal */ identifiers: Map; /* @internal */ nodeCount: number; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6b21f2a8ee166..193a48109f065 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1643,7 +1643,7 @@ namespace ts { // export default ... export function isAliasSymbolDeclaration(node: Node): boolean { return node.kind === SyntaxKind.ImportEqualsDeclaration || - node.kind === SyntaxKind.GlobalModuleExportDeclaration || + node.kind === SyntaxKind.NamespaceExportDeclaration || node.kind === SyntaxKind.ImportClause && !!(node).name || node.kind === SyntaxKind.NamespaceImport || node.kind === SyntaxKind.ImportSpecifier || diff --git a/tests/baselines/reference/umd-augmentation-3.symbols b/tests/baselines/reference/umd-augmentation-3.symbols index 4923c17954f88..3193e83cd1979 100644 --- a/tests/baselines/reference/umd-augmentation-3.symbols +++ b/tests/baselines/reference/umd-augmentation-3.symbols @@ -44,7 +44,7 @@ export = M2D; >M2D : Symbol(M2D, Decl(index.d.ts, 3, 13)) declare namespace M2D { ->M2D : Symbol(, Decl(index.d.ts, 3, 13), Decl(math2d-augment.d.ts, 0, 33)) +>M2D : Symbol(Math2d, Decl(index.d.ts, 3, 13), Decl(math2d-augment.d.ts, 0, 33)) interface Point { >Point : Symbol(Point, Decl(index.d.ts, 5, 23)) diff --git a/tests/baselines/reference/umd-augmentation-3.types b/tests/baselines/reference/umd-augmentation-3.types index 09a383dc881d8..854ebceff379c 100644 --- a/tests/baselines/reference/umd-augmentation-3.types +++ b/tests/baselines/reference/umd-augmentation-3.types @@ -54,7 +54,7 @@ export = M2D; >M2D : typeof M2D declare namespace M2D { ->M2D : typeof +>M2D : typeof Math2d interface Point { >Point : Point diff --git a/tests/baselines/reference/umd5.errors.txt b/tests/baselines/reference/umd5.errors.txt index 19529ce195a6c..9628ad738db86 100644 --- a/tests/baselines/reference/umd5.errors.txt +++ b/tests/baselines/reference/umd5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/externalModules/a.ts(6,9): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: Identifier 'Foo' must be imported from a module ==== tests/cases/conformance/externalModules/a.ts (1 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/externalModules/a.ts(6,9): error TS2304: Cannot find nam // should error let z = Foo; ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2686: Identifier 'Foo' must be imported from a module ==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== diff --git a/tests/baselines/reference/umd5.js b/tests/baselines/reference/umd5.js index d054daf93fd61..f8e2321a0f16c 100644 --- a/tests/baselines/reference/umd5.js +++ b/tests/baselines/reference/umd5.js @@ -23,4 +23,4 @@ Bar.fn(); var x; var y = x.n; // should error -var z = Foo; +var z = exports.Foo;