Skip to content

Commit cd0b085

Browse files
Merge branch 'master' into literalTypeWidening
Conflicts: tests/baselines/reference/assignmentCompat1.errors.txt tests/baselines/reference/assignmentCompatability_checking-apply-member-off-of-function-interface.errors.txt tests/baselines/reference/assignmentCompatability_checking-call-member-off-of-function-interface.errors.txt tests/baselines/reference/booleanAssignment.errors.txt tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt tests/baselines/reference/destructuringParameterDeclaration2.errors.txt tests/baselines/reference/destructuringParameterDeclaration4.errors.txt tests/baselines/reference/parseClassDeclarationInStrictModeByDefaultInES6.errors.txt tests/baselines/reference/returnInConstructor1.errors.txt tests/baselines/reference/typeArgumentConstraintResolution1.errors.txt
2 parents fe1f12c + ebfdeaa commit cd0b085

File tree

258 files changed

+7966
-582
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

258 files changed

+7966
-582
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"istanbul": "latest",
3737
"mocha-fivemat-progress-reporter": "latest",
3838
"tslint": "next",
39-
"typescript": "1.8.0-dev.20160113",
39+
"typescript": "next",
4040
"tsd": "latest"
4141
},
4242
"scripts": {

src/compiler/binder.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ namespace ts {
131131
options = opts;
132132
inStrictMode = !!file.externalModuleIndicator;
133133
classifiableNames = {};
134+
134135
Symbol = objectAllocator.getSymbolConstructor();
135136

136137
if (!file.locals) {
@@ -191,8 +192,8 @@ namespace ts {
191192
// unless it is a well known Symbol.
192193
function getDeclarationName(node: Declaration): string {
193194
if (node.name) {
194-
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
195-
return `"${(<LiteralExpression>node.name).text}"`;
195+
if (isAmbientModule(node)) {
196+
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>node.name).text}"`;
196197
}
197198
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
198199
const nameExpression = (<ComputedPropertyName>node.name).expression;
@@ -348,7 +349,12 @@ namespace ts {
348349
// 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
349350
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
350351
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
351-
if (hasExportModifier || container.flags & NodeFlags.ExportContext) {
352+
353+
// NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
354+
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
355+
// and this case is specially handled. Module augmentations should only be merged with original module definition
356+
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
357+
if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) {
352358
const exportKind =
353359
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
354360
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
@@ -843,7 +849,10 @@ namespace ts {
843849

844850
function bindModuleDeclaration(node: ModuleDeclaration) {
845851
setExportContextFlag(node);
846-
if (node.name.kind === SyntaxKind.StringLiteral) {
852+
if (isAmbientModule(node)) {
853+
if (node.flags & NodeFlags.Export) {
854+
errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
855+
}
847856
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
848857
}
849858
else {

src/compiler/checker.ts

+255-151
Large diffs are not rendered by default.

src/compiler/core.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,8 @@ namespace ts {
718718
}
719719

720720
// Find the component that differs
721-
for (var joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
721+
let joinStartIndex: number;
722+
for (joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
722723
if (getCanonicalFileName(directoryComponents[joinStartIndex]) !== getCanonicalFileName(pathComponents[joinStartIndex])) {
723724
break;
724725
}

src/compiler/declarationEmitter.ts

+34-5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ namespace ts {
5454
let writer = createAndSetNewTextWriterWithSymbolWriter();
5555

5656
let enclosingDeclaration: Node;
57+
let resultHasExternalModuleIndicator: boolean;
5758
let currentText: string;
5859
let currentLineMap: number[];
5960
let currentIdentifiers: Map<string>;
@@ -101,6 +102,7 @@ namespace ts {
101102
});
102103
}
103104

105+
resultHasExternalModuleIndicator = false;
104106
if (!isBundledEmit || !isExternalModule(sourceFile)) {
105107
noDeclare = false;
106108
emitSourceFile(sourceFile);
@@ -139,6 +141,14 @@ namespace ts {
139141
allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo);
140142
moduleElementDeclarationEmitInfo = [];
141143
}
144+
145+
if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
146+
// if file was external module with augmentations - this fact should be preserved in .d.ts as well.
147+
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
148+
// that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
149+
write("export {};");
150+
writeLine();
151+
}
142152
});
143153

144154
return {
@@ -721,16 +731,25 @@ namespace ts {
721731
writer.writeLine();
722732
}
723733

724-
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration) {
734+
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) {
735+
// emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
736+
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
737+
// external modules since they are indistingushable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
738+
// so compiler will treat them as external modules.
739+
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration;
725740
let moduleSpecifier: Node;
726741
if (parent.kind === SyntaxKind.ImportEqualsDeclaration) {
727742
const node = parent as ImportEqualsDeclaration;
728743
moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node);
729744
}
745+
else if (parent.kind === SyntaxKind.ModuleDeclaration) {
746+
moduleSpecifier = (<ModuleDeclaration>parent).name;
747+
}
730748
else {
731749
const node = parent as (ImportDeclaration | ExportDeclaration);
732750
moduleSpecifier = node.moduleSpecifier;
733751
}
752+
734753
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
735754
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent);
736755
if (moduleName) {
@@ -784,13 +803,23 @@ namespace ts {
784803
function writeModuleDeclaration(node: ModuleDeclaration) {
785804
emitJsDocComments(node);
786805
emitModuleElementDeclarationFlags(node);
787-
if (node.flags & NodeFlags.Namespace) {
788-
write("namespace ");
806+
if (isGlobalScopeAugmentation(node)) {
807+
write("global ");
789808
}
790809
else {
791-
write("module ");
810+
if (node.flags & NodeFlags.Namespace) {
811+
write("namespace ");
812+
}
813+
else {
814+
write("module ");
815+
}
816+
if (isExternalModuleAugmentation(node)) {
817+
emitExternalModuleSpecifier(node);
818+
}
819+
else {
820+
writeTextOfNode(currentText, node.name);
821+
}
792822
}
793-
writeTextOfNode(currentText, node.name);
794823
while (node.body.kind !== SyntaxKind.ModuleBlock) {
795824
node = <ModuleDeclaration>node.body;
796825
write(".");

src/compiler/diagnosticMessages.json

+28
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,34 @@
17751775
"category": "Error",
17761776
"code": 2663
17771777
},
1778+
"Invalid module name in augmentation, module '{0}' cannot be found.": {
1779+
"category": "Error",
1780+
"code": 2664
1781+
},
1782+
"Module augmentation cannot introduce new names in the top level scope.": {
1783+
"category": "Error",
1784+
"code": 2665
1785+
},
1786+
"Exports and export assignments are not permitted in module augmentations.": {
1787+
"category": "Error",
1788+
"code": 2666
1789+
},
1790+
"Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.": {
1791+
"category": "Error",
1792+
"code": 2667
1793+
},
1794+
"'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible.": {
1795+
"category": "Error",
1796+
"code": 2668
1797+
},
1798+
"Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.": {
1799+
"category": "Error",
1800+
"code": 2669
1801+
},
1802+
"Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.": {
1803+
"category": "Error",
1804+
"code": 2670
1805+
},
17781806
"Import declaration '{0}' is using private name '{1}'.": {
17791807
"category": "Error",
17801808
"code": 4000

src/compiler/emitter.ts

+11-16
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
319319
};`;
320320

321321
const awaiterHelper = `
322-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
323-
return new Promise(function (resolve, reject) {
324-
generator = generator.call(thisArg, _arguments);
325-
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
326-
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
327-
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
328-
function step(verb, value) {
329-
var result = generator[verb](value);
330-
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
331-
}
332-
step("next", void 0);
322+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
323+
return new P(function (resolve, reject) {
324+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
325+
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
326+
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
327+
step((generator = generator.call(thisArg, _arguments)).next());
333328
});
334329
};`;
335330

@@ -1250,7 +1245,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
12501245
else {
12511246
// One object literal with all the attributes in them
12521247
write("{");
1253-
for (var i = 0; i < attrs.length; i++) {
1248+
for (let i = 0, n = attrs.length; i < n; i++) {
12541249
if (i > 0) {
12551250
write(", ");
12561251
}
@@ -1262,7 +1257,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
12621257

12631258
// Children
12641259
if (children) {
1265-
for (var i = 0; i < children.length; i++) {
1260+
for (let i = 0; i < children.length; i++) {
12661261
// Don't emit empty expressions
12671262
if (children[i].kind === SyntaxKind.JsxExpression && !((<JsxExpression>children[i]).expression)) {
12681263
continue;
@@ -1356,7 +1351,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
13561351
function emitJsxElement(node: JsxElement) {
13571352
emitJsxOpeningOrSelfClosingElement(node.openingElement);
13581353

1359-
for (var i = 0, n = node.children.length; i < n; i++) {
1354+
for (let i = 0, n = node.children.length; i < n; i++) {
13601355
emit(node.children[i]);
13611356
}
13621357

@@ -5172,7 +5167,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
51725167
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
51735168

51745169
if (isClassExpressionWithStaticProperties) {
5175-
for (var property of staticProperties) {
5170+
for (const property of staticProperties) {
51765171
write(",");
51775172
writeLine();
51785173
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
@@ -5719,7 +5714,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
57195714
const parameters = valueDeclaration.parameters;
57205715
const parameterCount = parameters.length;
57215716
if (parameterCount > 0) {
5722-
for (var i = 0; i < parameterCount; i++) {
5717+
for (let i = 0; i < parameterCount; i++) {
57235718
if (i > 0) {
57245719
write(", ");
57255720
}

src/compiler/parser.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -4430,6 +4430,9 @@ namespace ts {
44304430
}
44314431
continue;
44324432

4433+
case SyntaxKind.GlobalKeyword:
4434+
return nextToken() === SyntaxKind.OpenBraceToken;
4435+
44334436
case SyntaxKind.ImportKeyword:
44344437
nextToken();
44354438
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
@@ -4494,6 +4497,7 @@ namespace ts {
44944497
case SyntaxKind.ModuleKeyword:
44954498
case SyntaxKind.NamespaceKeyword:
44964499
case SyntaxKind.TypeKeyword:
4500+
case SyntaxKind.GlobalKeyword:
44974501
// When these don't start a declaration, they're an identifier in an expression statement
44984502
return true;
44994503

@@ -4582,6 +4586,7 @@ namespace ts {
45824586
case SyntaxKind.PublicKeyword:
45834587
case SyntaxKind.AbstractKeyword:
45844588
case SyntaxKind.StaticKeyword:
4589+
case SyntaxKind.GlobalKeyword:
45854590
if (isStartOfDeclaration()) {
45864591
return parseDeclaration();
45874592
}
@@ -4609,6 +4614,7 @@ namespace ts {
46094614
return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
46104615
case SyntaxKind.EnumKeyword:
46114616
return parseEnumDeclaration(fullStart, decorators, modifiers);
4617+
case SyntaxKind.GlobalKeyword:
46124618
case SyntaxKind.ModuleKeyword:
46134619
case SyntaxKind.NamespaceKeyword:
46144620
return parseModuleDeclaration(fullStart, decorators, modifiers);
@@ -5243,14 +5249,25 @@ namespace ts {
52435249
const node = <ModuleDeclaration>createNode(SyntaxKind.ModuleDeclaration, fullStart);
52445250
node.decorators = decorators;
52455251
setModifiers(node, modifiers);
5246-
node.name = parseLiteralNode(/*internName*/ true);
5252+
if (token === SyntaxKind.GlobalKeyword) {
5253+
// parse 'global' as name of global scope augmentation
5254+
node.name = parseIdentifier();
5255+
node.flags |= NodeFlags.GlobalAugmentation;
5256+
}
5257+
else {
5258+
node.name = parseLiteralNode(/*internName*/ true);
5259+
}
52475260
node.body = parseModuleBlock();
52485261
return finishNode(node);
52495262
}
52505263

52515264
function parseModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ModuleDeclaration {
52525265
let flags = modifiers ? modifiers.flags : 0;
5253-
if (parseOptional(SyntaxKind.NamespaceKeyword)) {
5266+
if (token === SyntaxKind.GlobalKeyword) {
5267+
// global augmentation
5268+
return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
5269+
}
5270+
else if (parseOptional(SyntaxKind.NamespaceKeyword)) {
52545271
flags |= NodeFlags.Namespace;
52555272
}
52565273
else {

0 commit comments

Comments
 (0)