Skip to content

Commit 87825ee

Browse files
committed
Merge pull request microsoft#5024 from Microsoft/importsInAmbientModules
collect imports and exports in ambient external modules
2 parents 4ad2160 + b4f326a commit 87825ee

23 files changed

Lines changed: 244 additions & 19 deletions

src/compiler/checker.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -948,12 +948,6 @@ namespace ts {
948948
return symbol.flags & meaning ? symbol : resolveAlias(symbol);
949949
}
950950

951-
function isExternalModuleNameRelative(moduleName: string): boolean {
952-
// TypeScript 1.0 spec (April 2014): 11.2.1
953-
// An external module name is "relative" if the first term is "." or "..".
954-
return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
955-
}
956-
957951
function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol {
958952
if (moduleReferenceExpression.kind !== SyntaxKind.StringLiteral) {
959953
return;

src/compiler/program.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,12 @@ namespace ts {
692692

693693
let imports: LiteralExpression[];
694694
for (let node of file.statements) {
695+
collect(node, /* allowRelativeModuleNames */ true);
696+
}
697+
698+
file.imports = imports || emptyArray;
699+
700+
function collect(node: Node, allowRelativeModuleNames: boolean): void {
695701
switch (node.kind) {
696702
case SyntaxKind.ImportDeclaration:
697703
case SyntaxKind.ImportEqualsDeclaration:
@@ -704,7 +710,9 @@ namespace ts {
704710
break;
705711
}
706712

707-
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
713+
if (allowRelativeModuleNames || !isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
714+
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
715+
}
708716
break;
709717
case SyntaxKind.ModuleDeclaration:
710718
if ((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
@@ -714,23 +722,15 @@ namespace ts {
714722
// The StringLiteral must specify a top - level external module name.
715723
// Relative external module names are not permitted
716724
forEachChild((<ModuleDeclaration>node).body, node => {
717-
if (isExternalModuleImportEqualsDeclaration(node) &&
718-
getExternalModuleImportEqualsDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
719-
let moduleName = <LiteralExpression>getExternalModuleImportEqualsDeclarationExpression(node);
720-
// TypeScript 1.0 spec (April 2014): 12.1.6
721-
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
722-
// only through top - level external module names. Relative external module names are not permitted.
723-
if (moduleName) {
724-
(imports || (imports = [])).push(moduleName);
725-
}
726-
}
725+
// TypeScript 1.0 spec (April 2014): 12.1.6
726+
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
727+
// only through top - level external module names. Relative external module names are not permitted.
728+
collect(node, /* allowRelativeModuleNames */ false);
727729
});
728730
}
729731
break;
730732
}
731733
}
732-
733-
file.imports = imports || emptyArray;
734734
}
735735

736736
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,12 @@ namespace ts {
992992
}
993993
return false;
994994
}
995+
996+
export function isExternalModuleNameRelative(moduleName: string): boolean {
997+
// TypeScript 1.0 spec (April 2014): 11.2.1
998+
// An external module name is "relative" if the first term is "." or "..".
999+
return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
1000+
}
9951001

9961002
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
9971003
let moduleState = getModuleInstanceState(node);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [tests/cases/compiler/exportsInAmbientModules1.ts] ////
2+
3+
//// [external.d.ts]
4+
5+
export var x: number
6+
7+
//// [main.ts]
8+
9+
declare module "M" {
10+
export {x} from "external"
11+
}
12+
13+
//// [main.js]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/external.d.ts ===
2+
3+
export var x: number
4+
>x : Symbol(x, Decl(external.d.ts, 1, 10))
5+
6+
=== tests/cases/compiler/main.ts ===
7+
8+
declare module "M" {
9+
export {x} from "external"
10+
>x : Symbol(x, Decl(main.ts, 2, 12))
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/external.d.ts ===
2+
3+
export var x: number
4+
>x : number
5+
6+
=== tests/cases/compiler/main.ts ===
7+
8+
declare module "M" {
9+
export {x} from "external"
10+
>x : number
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [tests/cases/compiler/exportsInAmbientModules2.ts] ////
2+
3+
//// [external.d.ts]
4+
5+
export default class C {}
6+
7+
//// [main.ts]
8+
9+
declare module "M" {
10+
export * from "external"
11+
}
12+
13+
//// [main.js]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/external.d.ts ===
2+
3+
export default class C {}
4+
>C : Symbol(C, Decl(external.d.ts, 0, 0))
5+
6+
=== tests/cases/compiler/main.ts ===
7+
8+
No type information for this code.declare module "M" {
9+
No type information for this code. export * from "external"
10+
No type information for this code.}
11+
No type information for this code.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/external.d.ts ===
2+
3+
export default class C {}
4+
>C : C
5+
6+
=== tests/cases/compiler/main.ts ===
7+
8+
No type information for this code.declare module "M" {
9+
No type information for this code. export * from "external"
10+
No type information for this code.}
11+
No type information for this code.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [tests/cases/compiler/importsInAmbientModules1.ts] ////
2+
3+
//// [external.d.ts]
4+
5+
export var x: number
6+
7+
//// [main.ts]
8+
9+
declare module "M" {
10+
import {x} from "external"
11+
}
12+
13+
//// [main.js]

0 commit comments

Comments
 (0)