Skip to content

Commit c399274

Browse files
Merge pull request microsoft#1635 from Microsoft/recoverFromForcePush
Recover from force push
2 parents 7a8e3ec + 5562810 commit c399274

21 files changed

+339
-70
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,6 @@ module ts {
15751575
case SyntaxKind.IndexSignature:
15761576
case SyntaxKind.Parameter:
15771577
case SyntaxKind.ModuleBlock:
1578-
case SyntaxKind.TypeParameter:
15791578
case SyntaxKind.FunctionType:
15801579
case SyntaxKind.ConstructorType:
15811580
case SyntaxKind.TypeLiteral:
@@ -1585,7 +1584,9 @@ module ts {
15851584
case SyntaxKind.UnionType:
15861585
case SyntaxKind.ParenthesizedType:
15871586
return isDeclarationVisible(<Declaration>node.parent);
1588-
1587+
1588+
// Type parameters are always visible
1589+
case SyntaxKind.TypeParameter:
15891590
// Source file is always visible
15901591
case SyntaxKind.SourceFile:
15911592
return true;
@@ -3651,9 +3652,7 @@ module ts {
36513652
var maybeCache = maybeStack[depth];
36523653
// If result is definitely true, copy assumptions to global cache, else copy to next level up
36533654
var destinationCache = result === Ternary.True || depth === 0 ? relation : maybeStack[depth - 1];
3654-
for (var p in maybeCache) {
3655-
destinationCache[p] = maybeCache[p];
3656-
}
3655+
copyMap(/*source*/maybeCache, /*target*/destinationCache);
36573656
}
36583657
else {
36593658
// A false result goes straight into global cache (when something is false under assumptions it
@@ -9000,7 +8999,12 @@ module ts {
90008999
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
90019000
checkExportsOnMergedDeclarations(node);
90029001
var symbol = getSymbolOfNode(node);
9003-
if (symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length > 1 && !isInAmbientContext(node)) {
9002+
9003+
// The following checks only apply on a non-ambient instantiated module declaration.
9004+
if (symbol.flags & SymbolFlags.ValueModule
9005+
&& symbol.declarations.length > 1
9006+
&& !isInAmbientContext(node)
9007+
&& isInstantiatedModule(node, compilerOptions.preserveConstEnums)) {
90049008
var classOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
90059009
if (classOrFunc) {
90069010
if (getSourceFileOfNode(node) !== getSourceFileOfNode(classOrFunc)) {
@@ -9011,6 +9015,8 @@ module ts {
90119015
}
90129016
}
90139017
}
9018+
9019+
// Checks for ambient external modules.
90149020
if (node.name.kind === SyntaxKind.StringLiteral) {
90159021
if (!isGlobalSourceFile(node.parent)) {
90169022
error(node.name, Diagnostics.Ambient_external_modules_cannot_be_nested_in_other_modules);

src/compiler/core.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ module ts {
208208
return result;
209209
}
210210

211+
export function copyMap<T>(source: Map<T>, target: Map<T>): void {
212+
for (var p in source) {
213+
target[p] = source[p];
214+
}
215+
}
216+
211217
/**
212218
* Creates a map from the elements of an array.
213219
*

src/compiler/emitter.ts

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,18 +1461,7 @@ module ts {
14611461
referencePathsOutput,
14621462
}
14631463
}
1464-
1465-
export interface EmitHost extends ScriptReferenceHost {
1466-
getSourceFiles(): SourceFile[];
1467-
isEmitBlocked(sourceFile?: SourceFile): boolean;
1468-
1469-
getCommonSourceDirectory(): string;
1470-
getCanonicalFileName(fileName: string): string;
1471-
getNewLine(): string;
1472-
1473-
writeFile(filename: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
1474-
}
1475-
1464+
14761465
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
14771466
var diagnostics: Diagnostic[] = [];
14781467
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
@@ -2068,9 +2057,15 @@ module ts {
20682057
write("(");
20692058
}
20702059

2071-
emitLiteral(node.head);
2060+
var headEmitted = false;
2061+
if (shouldEmitTemplateHead()) {
2062+
emitLiteral(node.head);
2063+
headEmitted = true;
2064+
}
2065+
2066+
for (var i = 0; i < node.templateSpans.length; i++) {
2067+
var templateSpan = node.templateSpans[i];
20722068

2073-
forEach(node.templateSpans, templateSpan => {
20742069
// Check if the expression has operands and binds its operands less closely than binary '+'.
20752070
// If it does, we need to wrap the expression in parentheses. Otherwise, something like
20762071
// `abc${ 1 << 2 }`
@@ -2082,7 +2077,14 @@ module ts {
20822077
// "abc" + (1 << 2) + ""
20832078
var needsParens = templateSpan.expression.kind !== SyntaxKind.ParenthesizedExpression
20842079
&& comparePrecedenceToBinaryPlus(templateSpan.expression) !== Comparison.GreaterThan;
2085-
write(" + ");
2080+
2081+
if (i > 0 || headEmitted) {
2082+
// If this is the first span and the head was not emitted, then this templateSpan's
2083+
// expression will be the first to be emitted. Don't emit the preceding ' + ' in that
2084+
// case.
2085+
write(" + ");
2086+
}
2087+
20862088
emitParenthesized(templateSpan.expression, needsParens);
20872089
// Only emit if the literal is non-empty.
20882090
// The binary '+' operator is left-associative, so the first string concatenation
@@ -2092,12 +2094,34 @@ module ts {
20922094
write(" + ")
20932095
emitLiteral(templateSpan.literal);
20942096
}
2095-
});
2097+
}
20962098

20972099
if (emitOuterParens) {
20982100
write(")");
20992101
}
21002102

2103+
function shouldEmitTemplateHead() {
2104+
// If this expression has an empty head literal and the first template span has a non-empty
2105+
// literal, then emitting the empty head literal is not necessary.
2106+
// `${ foo } and ${ bar }`
2107+
// can be emitted as
2108+
// foo + " and " + bar
2109+
// This is because it is only required that one of the first two operands in the emit
2110+
// output must be a string literal, so that the other operand and all following operands
2111+
// are forced into strings.
2112+
//
2113+
// If the first template span has an empty literal, then the head must still be emitted.
2114+
// `${ foo }${ bar }`
2115+
// must still be emitted as
2116+
// "" + foo + bar
2117+
2118+
// There is always atleast one templateSpan in this code path, since
2119+
// NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
2120+
Debug.assert(node.templateSpans.length !== 0);
2121+
2122+
return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
2123+
}
2124+
21012125
function templateNeedsParens(template: TemplateExpression, parent: Expression) {
21022126
switch (parent.kind) {
21032127
case SyntaxKind.CallExpression:
@@ -3686,8 +3710,8 @@ module ts {
36863710
}
36873711

36883712
function emitModuleDeclaration(node: ModuleDeclaration) {
3689-
var shouldEmit = getModuleInstanceState(node) === ModuleInstanceState.Instantiated ||
3690-
(getModuleInstanceState(node) === ModuleInstanceState.ConstEnumOnly && compilerOptions.preserveConstEnums);
3713+
// Emit only if this module is non-ambient.
3714+
var shouldEmit = isInstantiatedModule(node, compilerOptions.preserveConstEnums);
36913715

36923716
if (!shouldEmit) {
36933717
return emitPinnedOrTripleSlashComments(node);

src/compiler/utilities.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ module ts {
2323
string(): string;
2424
}
2525

26+
export interface EmitHost extends ScriptReferenceHost {
27+
getSourceFiles(): SourceFile[];
28+
isEmitBlocked(sourceFile?: SourceFile): boolean;
29+
30+
getCommonSourceDirectory(): string;
31+
getCanonicalFileName(fileName: string): string;
32+
getNewLine(): string;
33+
34+
writeFile(filename: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
35+
}
36+
2637
// Pool writers to avoid needing to allocate them for every symbol we write.
2738
var stringWriters: StringSymbolWriter[] = [];
2839
export function getSingleLineStringWriter(): StringSymbolWriter {
@@ -525,6 +536,12 @@ module ts {
525536
return false;
526537
}
527538

539+
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
540+
var moduleState = getModuleInstanceState(node)
541+
return moduleState === ModuleInstanceState.Instantiated ||
542+
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
543+
}
544+
528545
export function isExternalModuleImportDeclaration(node: Node) {
529546
return node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
530547
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts(2,8): error TS2434: A module declaration cannot be located prior to a class or function with which it is merged
2+
3+
4+
==== tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts (1 errors) ====
5+
// Non-ambient & instantiated module.
6+
module Moclodule {
7+
~~~~~~~~~
8+
!!! error TS2434: A module declaration cannot be located prior to a class or function with which it is merged
9+
export interface Someinterface {
10+
foo(): void;
11+
}
12+
var x = 10;
13+
}
14+
15+
class Moclodule {
16+
}
17+
18+
// Instantiated module.
19+
module Moclodule {
20+
export class Manager {
21+
}
22+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [cloduleWithPriorInstantiatedModule.ts]
2+
// Non-ambient & instantiated module.
3+
module Moclodule {
4+
export interface Someinterface {
5+
foo(): void;
6+
}
7+
var x = 10;
8+
}
9+
10+
class Moclodule {
11+
}
12+
13+
// Instantiated module.
14+
module Moclodule {
15+
export class Manager {
16+
}
17+
}
18+
19+
//// [cloduleWithPriorInstantiatedModule.js]
20+
// Non-ambient & instantiated module.
21+
var Moclodule;
22+
(function (Moclodule) {
23+
var x = 10;
24+
})(Moclodule || (Moclodule = {}));
25+
var Moclodule = (function () {
26+
function Moclodule() {
27+
}
28+
return Moclodule;
29+
})();
30+
// Instantiated module.
31+
var Moclodule;
32+
(function (Moclodule) {
33+
var Manager = (function () {
34+
function Manager() {
35+
}
36+
return Manager;
37+
})();
38+
Moclodule.Manager = Manager;
39+
})(Moclodule || (Moclodule = {}));
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [cloduleWithPriorUninstantiatedModule.ts]
2+
// Non-ambient & uninstantiated module.
3+
module Moclodule {
4+
export interface Someinterface {
5+
foo(): void;
6+
}
7+
}
8+
9+
class Moclodule {
10+
}
11+
12+
// Instantiated module.
13+
module Moclodule {
14+
export class Manager {
15+
}
16+
}
17+
18+
//// [cloduleWithPriorUninstantiatedModule.js]
19+
var Moclodule = (function () {
20+
function Moclodule() {
21+
}
22+
return Moclodule;
23+
})();
24+
// Instantiated module.
25+
var Moclodule;
26+
(function (Moclodule) {
27+
var Manager = (function () {
28+
function Manager() {
29+
}
30+
return Manager;
31+
})();
32+
Moclodule.Manager = Manager;
33+
})(Moclodule || (Moclodule = {}));
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/cloduleWithPriorUninstantiatedModule.ts ===
2+
// Non-ambient & uninstantiated module.
3+
module Moclodule {
4+
>Moclodule : typeof Moclodule
5+
6+
export interface Someinterface {
7+
>Someinterface : Someinterface
8+
9+
foo(): void;
10+
>foo : () => void
11+
}
12+
}
13+
14+
class Moclodule {
15+
>Moclodule : Moclodule
16+
}
17+
18+
// Instantiated module.
19+
module Moclodule {
20+
>Moclodule : typeof Moclodule
21+
22+
export class Manager {
23+
>Manager : Manager
24+
}
25+
}

tests/baselines/reference/templateStringBinaryOperations.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,49 +55,49 @@ var l4 = 1 + `2${ 3 & 4 }5` + 6;
5555
//// [templateStringBinaryOperations.js]
5656
var a = 1 + ("" + 3);
5757
var b = 1 + ("2" + 3);
58-
var c = 1 + ("" + 3 + "4");
58+
var c = 1 + (3 + "4");
5959
var d = 1 + ("2" + 3 + "4");
6060
var e = ("" + 3) + 5;
6161
var f = ("2" + 3) + 5;
62-
var g = ("" + 3 + "4") + 5;
62+
var g = (3 + "4") + 5;
6363
var h = ("2" + 3 + "4") + 5;
6464
var i = 1 + ("" + 3) + 5;
6565
var j = 1 + ("2" + 3) + 5;
66-
var k = 1 + ("" + 3 + "4") + 5;
66+
var k = 1 + (3 + "4") + 5;
6767
var l = 1 + ("2" + 3 + "4") + 5;
6868
var a2 = 1 + ("" + (3 - 4));
6969
var b2 = 1 + ("2" + (3 - 4));
70-
var c2 = 1 + ("" + (3 - 4) + "5");
70+
var c2 = 1 + ((3 - 4) + "5");
7171
var d2 = 1 + ("2" + (3 - 4) + "5");
7272
var e2 = ("" + (3 - 4)) + 6;
7373
var f2 = ("2" + (3 - 4)) + 6;
74-
var g2 = ("" + (3 - 4) + "5") + 6;
74+
var g2 = ((3 - 4) + "5") + 6;
7575
var h2 = ("2" + (3 - 4) + "5") + 6;
7676
var i2 = 1 + ("" + (3 - 4)) + 6;
7777
var j2 = 1 + ("2" + (3 - 4)) + 6;
78-
var k2 = 1 + ("" + (3 - 4) + "5") + 6;
78+
var k2 = 1 + ((3 - 4) + "5") + 6;
7979
var l2 = 1 + ("2" + (3 - 4) + "5") + 6;
8080
var a3 = 1 + ("" + 3 * 4);
8181
var b3 = 1 + ("2" + 3 * 4);
82-
var c3 = 1 + ("" + 3 * 4 + "5");
82+
var c3 = 1 + (3 * 4 + "5");
8383
var d3 = 1 + ("2" + 3 * 4 + "5");
8484
var e3 = ("" + 3 * 4) + 6;
8585
var f3 = ("2" + 3 * 4) + 6;
86-
var g3 = ("" + 3 * 4 + "5") + 6;
86+
var g3 = (3 * 4 + "5") + 6;
8787
var h3 = ("2" + 3 * 4 + "5") + 6;
8888
var i3 = 1 + ("" + 3 * 4) + 6;
8989
var j3 = 1 + ("2" + 3 * 4) + 6;
90-
var k3 = 1 + ("" + 3 * 4 + "5") + 6;
90+
var k3 = 1 + (3 * 4 + "5") + 6;
9191
var l3 = 1 + ("2" + 3 * 4 + "5") + 6;
9292
var a4 = 1 + ("" + (3 & 4));
9393
var b4 = 1 + ("2" + (3 & 4));
94-
var c4 = 1 + ("" + (3 & 4) + "5");
94+
var c4 = 1 + ((3 & 4) + "5");
9595
var d4 = 1 + ("2" + (3 & 4) + "5");
9696
var e4 = ("" + (3 & 4)) + 6;
9797
var f4 = ("2" + (3 & 4)) + 6;
98-
var g4 = ("" + (3 & 4) + "5") + 6;
98+
var g4 = ((3 & 4) + "5") + 6;
9999
var h4 = ("2" + (3 & 4) + "5") + 6;
100100
var i4 = 1 + ("" + (3 & 4)) + 6;
101101
var j4 = 1 + ("2" + (3 & 4)) + 6;
102-
var k4 = 1 + ("" + (3 & 4) + "5") + 6;
102+
var k4 = 1 + ((3 & 4) + "5") + 6;
103103
var l4 = 1 + ("2" + (3 & 4) + "5") + 6;

0 commit comments

Comments
 (0)