Skip to content

Commit 7dc0af4

Browse files
committed
Merge pull request #6764 from Microsoft/port-6742
Port #6742 into release-1.8
2 parents b4bb5f3 + 32001ea commit 7dc0af4

38 files changed

+1709
-11
lines changed

Diff for: src/compiler/checker.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -391,10 +391,17 @@ namespace ts {
391391
if (!mainModule) {
392392
return;
393393
}
394-
// if module symbol has already been merged - it is safe to use it.
395-
// otherwise clone it
396-
mainModule = mainModule.flags & SymbolFlags.Merged ? mainModule : cloneSymbol(mainModule);
397-
mergeSymbol(mainModule, moduleAugmentation.symbol);
394+
// obtain item referenced by 'export='
395+
mainModule = resolveExternalModuleSymbol(mainModule);
396+
if (mainModule.flags & SymbolFlags.Namespace) {
397+
// if module symbol has already been merged - it is safe to use it.
398+
// otherwise clone it
399+
mainModule = mainModule.flags & SymbolFlags.Merged ? mainModule : cloneSymbol(mainModule);
400+
mergeSymbol(mainModule, moduleAugmentation.symbol);
401+
}
402+
else {
403+
error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
404+
}
398405
}
399406
}
400407

@@ -887,7 +894,7 @@ namespace ts {
887894
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
888895
}
889896
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
890-
return resolveSymbol(moduleSymbol.exports["export="]) || resolveSymbol(moduleSymbol);
897+
return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
891898
}
892899
return exportDefaultSymbol;
893900
}
@@ -1178,7 +1185,7 @@ namespace ts {
11781185
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
11791186
// and an external module with no 'export =' declaration resolves to the module itself.
11801187
function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol {
1181-
return moduleSymbol && resolveSymbol(moduleSymbol.exports["export="]) || moduleSymbol;
1188+
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports["export="])) || moduleSymbol;
11821189
}
11831190

11841191
// An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
@@ -1193,8 +1200,8 @@ namespace ts {
11931200
return symbol;
11941201
}
11951202

1196-
function getExportAssignmentSymbol(moduleSymbol: Symbol): Symbol {
1197-
return moduleSymbol.exports["export="];
1203+
function hasExportAssignmentSymbol(moduleSymbol: Symbol): boolean {
1204+
return moduleSymbol.exports["export="] !== undefined;
11981205
}
11991206

12001207
function getExportsOfModuleAsArray(moduleSymbol: Symbol): Symbol[] {
@@ -14836,7 +14843,7 @@ namespace ts {
1483614843
else {
1483714844
// export * from "foo"
1483814845
const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
14839-
if (moduleSymbol && moduleSymbol.exports["export="]) {
14846+
if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
1484014847
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
1484114848
}
1484214849
}
@@ -15660,7 +15667,7 @@ namespace ts {
1566015667
return true;
1566115668
}
1566215669

15663-
const hasExportAssignment = getExportAssignmentSymbol(moduleSymbol) !== undefined;
15670+
const hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
1566415671
// if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
1566515672
// otherwise it will return moduleSymbol itself
1566615673
moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
@@ -16019,7 +16026,7 @@ namespace ts {
1601916026
if (!isExternalOrCommonJsModule(file)) {
1602016027
mergeSymbolTable(globals, file.locals);
1602116028
}
16022-
if (file.moduleAugmentations) {
16029+
if (file.moduleAugmentations.length) {
1602316030
(augmentations || (augmentations = [])).push(file.moduleAugmentations);
1602416031
}
1602516032
});

Diff for: src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,10 @@
18111811
"category": "Error",
18121812
"code": 2670
18131813
},
1814+
"Cannot augment module '{0}' because it resolves to a non-module entity.": {
1815+
"category": "Error",
1816+
"code": 2671
1817+
},
18141818
"Import declaration '{0}' is using private name '{1}'.": {
18151819
"category": "Error",
18161820
"code": 4000
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
tests/cases/compiler/file2.ts(6,16): error TS2671: Cannot augment module './file1' because it resolves to a non-module entity.
2+
tests/cases/compiler/file3.ts(3,8): error TS2503: Cannot find namespace 'x'.
3+
4+
5+
==== tests/cases/compiler/file3.ts (1 errors) ====
6+
import x = require("./file1");
7+
import "./file2";
8+
let a: x.A; // should not work
9+
~
10+
!!! error TS2503: Cannot find namespace 'x'.
11+
==== tests/cases/compiler/file1.ts (0 errors) ====
12+
var x = 1;
13+
export = x;
14+
15+
==== tests/cases/compiler/file2.ts (1 errors) ====
16+
17+
import x = require("./file1");
18+
19+
// augmentation for './file1'
20+
// should error since './file1' does not have namespace meaning
21+
declare module "./file1" {
22+
~~~~~~~~~
23+
!!! error TS2671: Cannot augment module './file1' because it resolves to a non-module entity.
24+
interface A { a }
25+
}
26+

Diff for: tests/baselines/reference/augmentExportEquals1.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/compiler/augmentExportEquals1.ts] ////
2+
3+
//// [file1.ts]
4+
var x = 1;
5+
export = x;
6+
7+
//// [file2.ts]
8+
9+
import x = require("./file1");
10+
11+
// augmentation for './file1'
12+
// should error since './file1' does not have namespace meaning
13+
declare module "./file1" {
14+
interface A { a }
15+
}
16+
17+
//// [file3.ts]
18+
import x = require("./file1");
19+
import "./file2";
20+
let a: x.A; // should not work
21+
22+
//// [file1.js]
23+
define(["require", "exports"], function (require, exports) {
24+
"use strict";
25+
var x = 1;
26+
return x;
27+
});
28+
//// [file2.js]
29+
define(["require", "exports"], function (require, exports) {
30+
"use strict";
31+
});
32+
//// [file3.js]
33+
define(["require", "exports", "./file2"], function (require, exports) {
34+
"use strict";
35+
var a; // should not work
36+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
tests/cases/compiler/file2.ts(6,16): error TS2671: Cannot augment module 'file1' because it resolves to a non-module entity.
2+
tests/cases/compiler/file3.ts(3,8): error TS2503: Cannot find namespace 'x'.
3+
4+
5+
==== tests/cases/compiler/file3.ts (1 errors) ====
6+
import x = require("file1");
7+
import "file2";
8+
let a: x.A; // should not work
9+
~
10+
!!! error TS2503: Cannot find namespace 'x'.
11+
==== tests/cases/compiler/file1.d.ts (0 errors) ====
12+
13+
declare module "file1" {
14+
var x: number;
15+
export = x;
16+
}
17+
18+
==== tests/cases/compiler/file2.ts (1 errors) ====
19+
/// <reference path="file1.d.ts"/>
20+
import x = require("file1");
21+
22+
// augmentation for 'file1'
23+
// should error since 'file1' does not have namespace meaning
24+
declare module "file1" {
25+
~~~~~~~
26+
!!! error TS2671: Cannot augment module 'file1' because it resolves to a non-module entity.
27+
interface A { a }
28+
}
29+

Diff for: tests/baselines/reference/augmentExportEquals1_1.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [tests/cases/compiler/augmentExportEquals1_1.ts] ////
2+
3+
//// [file1.d.ts]
4+
5+
declare module "file1" {
6+
var x: number;
7+
export = x;
8+
}
9+
10+
//// [file2.ts]
11+
/// <reference path="file1.d.ts"/>
12+
import x = require("file1");
13+
14+
// augmentation for 'file1'
15+
// should error since 'file1' does not have namespace meaning
16+
declare module "file1" {
17+
interface A { a }
18+
}
19+
20+
//// [file3.ts]
21+
import x = require("file1");
22+
import "file2";
23+
let a: x.A; // should not work
24+
25+
//// [file2.js]
26+
define(["require", "exports"], function (require, exports) {
27+
"use strict";
28+
});
29+
//// [file3.js]
30+
define(["require", "exports", "file2"], function (require, exports) {
31+
"use strict";
32+
var a; // should not work
33+
});
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tests/cases/compiler/file2.ts(4,16): error TS2671: Cannot augment module './file1' because it resolves to a non-module entity.
2+
tests/cases/compiler/file3.ts(3,8): error TS2503: Cannot find namespace 'x'.
3+
4+
5+
==== tests/cases/compiler/file3.ts (1 errors) ====
6+
import x = require("./file1");
7+
import "./file2";
8+
let a: x.A; // should not work
9+
~
10+
!!! error TS2503: Cannot find namespace 'x'.
11+
==== tests/cases/compiler/file1.ts (0 errors) ====
12+
13+
function foo() {}
14+
export = foo;
15+
16+
==== tests/cases/compiler/file2.ts (1 errors) ====
17+
import x = require("./file1");
18+
19+
// should error since './file1' does not have namespace meaning
20+
declare module "./file1" {
21+
~~~~~~~~~
22+
!!! error TS2671: Cannot augment module './file1' because it resolves to a non-module entity.
23+
interface A { a }
24+
}
25+

Diff for: tests/baselines/reference/augmentExportEquals2.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//// [tests/cases/compiler/augmentExportEquals2.ts] ////
2+
3+
//// [file1.ts]
4+
5+
function foo() {}
6+
export = foo;
7+
8+
//// [file2.ts]
9+
import x = require("./file1");
10+
11+
// should error since './file1' does not have namespace meaning
12+
declare module "./file1" {
13+
interface A { a }
14+
}
15+
16+
//// [file3.ts]
17+
import x = require("./file1");
18+
import "./file2";
19+
let a: x.A; // should not work
20+
21+
//// [file1.js]
22+
define(["require", "exports"], function (require, exports) {
23+
"use strict";
24+
function foo() { }
25+
return foo;
26+
});
27+
//// [file2.js]
28+
define(["require", "exports"], function (require, exports) {
29+
"use strict";
30+
});
31+
//// [file3.js]
32+
define(["require", "exports", "./file2"], function (require, exports) {
33+
"use strict";
34+
var a; // should not work
35+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
tests/cases/compiler/file2.ts(6,16): error TS2671: Cannot augment module 'file1' because it resolves to a non-module entity.
2+
tests/cases/compiler/file3.ts(3,8): error TS2503: Cannot find namespace 'x'.
3+
4+
5+
==== tests/cases/compiler/file3.ts (1 errors) ====
6+
import x = require("file1");
7+
import "file2";
8+
let a: x.A; // should not work
9+
~
10+
!!! error TS2503: Cannot find namespace 'x'.
11+
==== tests/cases/compiler/file1.d.ts (0 errors) ====
12+
13+
declare module "file1" {
14+
function foo(): void;
15+
export = foo;
16+
}
17+
18+
==== tests/cases/compiler/file2.ts (1 errors) ====
19+
20+
/// <reference path="file1.d.ts"/>
21+
import x = require("file1");
22+
23+
// should error since './file1' does not have namespace meaning
24+
declare module "file1" {
25+
~~~~~~~
26+
!!! error TS2671: Cannot augment module 'file1' because it resolves to a non-module entity.
27+
interface A { a }
28+
}
29+

Diff for: tests/baselines/reference/augmentExportEquals2_1.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [tests/cases/compiler/augmentExportEquals2_1.ts] ////
2+
3+
//// [file1.d.ts]
4+
5+
declare module "file1" {
6+
function foo(): void;
7+
export = foo;
8+
}
9+
10+
//// [file2.ts]
11+
12+
/// <reference path="file1.d.ts"/>
13+
import x = require("file1");
14+
15+
// should error since './file1' does not have namespace meaning
16+
declare module "file1" {
17+
interface A { a }
18+
}
19+
20+
//// [file3.ts]
21+
import x = require("file1");
22+
import "file2";
23+
let a: x.A; // should not work
24+
25+
//// [file2.js]
26+
define(["require", "exports"], function (require, exports) {
27+
"use strict";
28+
});
29+
//// [file3.js]
30+
define(["require", "exports", "file2"], function (require, exports) {
31+
"use strict";
32+
var a; // should not work
33+
});
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
tests/cases/compiler/file2.ts(6,15): error TS2665: Module augmentation cannot introduce new names in the top level scope.
2+
tests/cases/compiler/file2.ts(7,9): error TS2665: Module augmentation cannot introduce new names in the top level scope.
3+
4+
5+
==== tests/cases/compiler/file1.ts (0 errors) ====
6+
7+
function foo() {}
8+
namespace foo {
9+
export var v = 1;
10+
}
11+
export = foo;
12+
13+
==== tests/cases/compiler/file2.ts (2 errors) ====
14+
import x = require("./file1");
15+
x.b = 1;
16+
17+
// OK - './file1' is a namespace
18+
declare module "./file1" {
19+
interface A { a }
20+
~
21+
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
22+
let b: number;
23+
~
24+
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
25+
}
26+
27+
==== tests/cases/compiler/file3.ts (0 errors) ====
28+
import * as x from "./file1";
29+
import "./file2";
30+
let a: x.A;
31+
let b = x.b;

0 commit comments

Comments
 (0)