Skip to content

Commit 9715052

Browse files
author
Kanchalai Tanglertsampan
committed
Merge branch 'master' into master-dynamicImport
2 parents d4754db + 0cb490e commit 9715052

4,869 files changed

Lines changed: 27874 additions & 31788 deletions

File tree

Some content is hidden

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

src/compiler/checker.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,9 +1507,23 @@ namespace ts {
15071507
}
15081508
}
15091509
else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) {
1510-
const left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessEntityNameExpression>name).expression;
1511-
const right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
1510+
let left: EntityNameOrEntityNameExpression;
15121511

1512+
if (name.kind === SyntaxKind.QualifiedName) {
1513+
left = (<QualifiedName>name).left;
1514+
}
1515+
else if (name.kind === SyntaxKind.PropertyAccessExpression &&
1516+
(name.expression.kind === SyntaxKind.ParenthesizedExpression || isEntityNameExpression(name.expression))) {
1517+
left = name.expression;
1518+
}
1519+
else {
1520+
// If the expression in property-access expression is not entity-name or parenthsizedExpression (e.g. it is a call expression), it won't be able to successfully resolve the name.
1521+
// This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression
1522+
// will attempt to checkPropertyAccessExpression to resolve symbol.
1523+
// i.e class C extends foo()./*do language service operation here*/B {}
1524+
return undefined;
1525+
}
1526+
const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name;
15131527
const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location);
15141528
if (!namespace || nodeIsMissing(right)) {
15151529
return undefined;
@@ -1525,6 +1539,15 @@ namespace ts {
15251539
return undefined;
15261540
}
15271541
}
1542+
else if (name.kind === SyntaxKind.ParenthesizedExpression) {
1543+
// If the expression in parenthsizedExpression is not an entity-name (e.g. it is a call expression), it won't be able to successfully resolve the name.
1544+
// This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression
1545+
// will attempt to checkPropertyAccessExpression to resolve symbol.
1546+
// i.e class C extends foo()./*do language service operation here*/B {}
1547+
return isEntityNameExpression(name.expression) ?
1548+
resolveEntityName(name.expression as EntityNameOrEntityNameExpression, meaning, ignoreErrors, dontResolveAlias, location) :
1549+
undefined;
1550+
}
15281551
else {
15291552
Debug.fail("Unknown entity name kind.");
15301553
}
@@ -21728,7 +21751,6 @@ namespace ts {
2172821751

2172921752
if (isHeritageClauseElementIdentifier(<EntityName>entityName)) {
2173021753
let meaning = SymbolFlags.None;
21731-
2173221754
// In an interface or class, we're definitely interested in a type.
2173321755
if (entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments) {
2173421756
meaning = SymbolFlags.Type;
@@ -21743,9 +21765,13 @@ namespace ts {
2174321765
}
2174421766

2174521767
meaning |= SymbolFlags.Alias;
21746-
return resolveEntityName(<EntityName>entityName, meaning);
21768+
const entityNameSymbol = resolveEntityName(<EntityName>entityName, meaning);
21769+
if (entityNameSymbol) {
21770+
return entityNameSymbol;
21771+
}
2174721772
}
21748-
else if (isPartOfExpression(entityName)) {
21773+
21774+
if (isPartOfExpression(entityName)) {
2174921775
if (nodeIsMissing(entityName)) {
2175021776
// Missing entity name.
2175121777
return undefined;

src/compiler/emitter.ts

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ namespace ts {
276276
function writeBundle(bundle: Bundle, output: EmitTextWriter) {
277277
const previousWriter = writer;
278278
setWriter(output);
279+
emitShebangIfNeeded(bundle);
280+
emitPrologueDirectivesIfNeeded(bundle);
279281
emitHelpersIndirect(bundle);
280282
for (const sourceFile of bundle.sourceFiles) {
281283
print(EmitHint.SourceFile, sourceFile, sourceFile);
@@ -287,6 +289,8 @@ namespace ts {
287289
function writeFile(sourceFile: SourceFile, output: EmitTextWriter) {
288290
const previousWriter = writer;
289291
setWriter(output);
292+
emitShebangIfNeeded(sourceFile);
293+
emitPrologueDirectivesIfNeeded(sourceFile);
290294
print(EmitHint.SourceFile, sourceFile, sourceFile);
291295
reset();
292296
writer = previousWriter;
@@ -738,15 +742,6 @@ namespace ts {
738742
return node && substituteNode && substituteNode(hint, node) || node;
739743
}
740744

741-
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
742-
if (emitBodyWithDetachedComments) {
743-
emitBodyWithDetachedComments(node, elements, emitCallback);
744-
}
745-
else {
746-
emitCallback(node);
747-
}
748-
}
749-
750745
function emitHelpersIndirect(node: Node) {
751746
if (onEmitHelpers) {
752747
onEmitHelpers(node, writeLines);
@@ -1664,7 +1659,12 @@ namespace ts {
16641659
? emitBlockFunctionBodyOnSingleLine
16651660
: emitBlockFunctionBodyWorker;
16661661

1667-
emitBodyIndirect(body, body.statements, emitBlockFunctionBody);
1662+
if (emitBodyWithDetachedComments) {
1663+
emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
1664+
}
1665+
else {
1666+
emitBlockFunctionBody(body);
1667+
}
16681668

16691669
decreaseIndent();
16701670
writeToken(SyntaxKind.CloseBraceToken, body.statements.end, body);
@@ -2073,16 +2073,27 @@ namespace ts {
20732073

20742074
function emitSourceFile(node: SourceFile) {
20752075
writeLine();
2076-
emitShebang();
2077-
emitBodyIndirect(node, node.statements, emitSourceFileWorker);
2076+
const statements = node.statements;
2077+
if (emitBodyWithDetachedComments) {
2078+
// Emit detached comment if there are no prologue directives or if the first node is synthesized.
2079+
// The synthesized node will have no leading comment so some comments may be missed.
2080+
const shouldEmitDetachedComment = statements.length === 0 ||
2081+
!isPrologueDirective(statements[0]) ||
2082+
nodeIsSynthesized(statements[0]);
2083+
if (shouldEmitDetachedComment) {
2084+
emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
2085+
return;
2086+
}
2087+
}
2088+
emitSourceFileWorker(node);
20782089
}
20792090

20802091
function emitSourceFileWorker(node: SourceFile) {
20812092
const statements = node.statements;
2082-
const statementOffset = emitPrologueDirectives(statements);
20832093
pushNameGenerationScope();
20842094
emitHelpersIndirect(node);
2085-
emitList(node, statements, ListFormat.MultiLine, statementOffset);
2095+
const index = findIndex(statements, statement => !isPrologueDirective(statement));
2096+
emitList(node, statements, ListFormat.MultiLine, index === -1 ? statements.length : index);
20862097
popNameGenerationScope();
20872098
}
20882099

@@ -2096,13 +2107,20 @@ namespace ts {
20962107
* Emits any prologue directives at the start of a Statement list, returning the
20972108
* number of prologue directives written to the output.
20982109
*/
2099-
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean): number {
2110+
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<String>): number {
21002111
for (let i = 0; i < statements.length; i++) {
2101-
if (isPrologueDirective(statements[i])) {
2102-
if (startWithNewLine || i > 0) {
2103-
writeLine();
2112+
const statement = statements[i];
2113+
if (isPrologueDirective(statement)) {
2114+
const shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
2115+
if (shouldEmitPrologueDirective) {
2116+
if (startWithNewLine || i > 0) {
2117+
writeLine();
2118+
}
2119+
emit(statement);
2120+
if (seenPrologueDirectives) {
2121+
seenPrologueDirectives.set(statement.expression.text, statement.expression.text);
2122+
}
21042123
}
2105-
emit(statements[i]);
21062124
}
21072125
else {
21082126
// return index of the first non prologue directive
@@ -2113,18 +2131,43 @@ namespace ts {
21132131
return statements.length;
21142132
}
21152133

2116-
//
2117-
// Helpers
2118-
//
2134+
function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
2135+
if (isSourceFile(sourceFileOrBundle)) {
2136+
setSourceFile(sourceFileOrBundle as SourceFile);
2137+
emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements);
2138+
}
2139+
else {
2140+
const seenPrologueDirectives = createMap<String>();
2141+
for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) {
2142+
setSourceFile(sourceFile);
2143+
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
2144+
}
2145+
}
2146+
}
21192147

2120-
function emitShebang() {
2121-
const shebang = getShebang(currentSourceFile.text);
2122-
if (shebang) {
2123-
write(shebang);
2124-
writeLine();
2148+
function emitShebangIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
2149+
if (isSourceFile(sourceFileOrBundle)) {
2150+
const shebang = getShebang(sourceFileOrBundle.text);
2151+
if (shebang) {
2152+
write(shebang);
2153+
writeLine();
2154+
return true;
2155+
}
2156+
}
2157+
else {
2158+
for (const sourceFile of sourceFileOrBundle.sourceFiles) {
2159+
// Emit only the first encountered shebang
2160+
if (emitShebangIfNeeded(sourceFile)) {
2161+
break;
2162+
}
2163+
}
21252164
}
21262165
}
21272166

2167+
//
2168+
// Helpers
2169+
//
2170+
21282171
function emitModifiers(node: Node, modifiers: NodeArray<Modifier>) {
21292172
if (modifiers && modifiers.length) {
21302173
emitList(node, modifiers, ListFormat.Modifiers);

src/compiler/transformers/generators.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,7 @@ namespace ts {
14781478
}
14791479

14801480
const initializer = node.initializer;
1481-
if (isVariableDeclarationList(initializer)) {
1481+
if (initializer && isVariableDeclarationList(initializer)) {
14821482
for (const variable of initializer.declarations) {
14831483
hoistVariableDeclaration(<Identifier>variable.name);
14841484
}

src/compiler/transformers/module/system.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,10 @@ namespace ts {
12851285
* @param node The node to visit.
12861286
*/
12871287
function visitForInitializer(node: ForInitializer): ForInitializer {
1288+
if (!node) {
1289+
return node;
1290+
}
1291+
12881292
if (shouldHoistForInitializer(node)) {
12891293
let expressions: Expression[];
12901294
for (const variable of node.declarations) {

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ namespace ts {
14071407
multiLine?: boolean;
14081408
}
14091409

1410-
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
1410+
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression | ParenthesizedExpression;
14111411
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
14121412

14131413
export interface PropertyAccessExpression extends MemberExpression, Declaration {

src/harness/harness.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1798,7 +1798,7 @@ namespace Harness {
17981798
if (currentFileContent === undefined) {
17991799
currentFileContent = "";
18001800
}
1801-
else {
1801+
else if (currentFileContent !== "") {
18021802
// End-of-line
18031803
currentFileContent = currentFileContent + "\n";
18041804
}

src/services/formatting/rules.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ namespace ts.formatting {
297297
// Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
298298
this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
299299
this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
300-
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
301-
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
300+
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
301+
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
302302
this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete));
303303

304304
// Insert new line after { and before } in multi-line contexts.

tests/baselines/reference/APISample_compile.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//// [APISample_compile.ts]
2-
32
/*
43
* Note: This test is a public API sample. The sample sources can be found
54
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
@@ -35,12 +34,12 @@ compile(process.argv.slice(2), {
3534
});
3635

3736
//// [APISample_compile.js]
37+
"use strict";
3838
/*
3939
* Note: This test is a public API sample. The sample sources can be found
4040
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
4141
* Please log a "breaking change" issue for any API breaking change affecting this issue
4242
*/
43-
"use strict";
4443
exports.__esModule = true;
4544
var ts = require("typescript");
4645
function compile(fileNames, options) {

tests/baselines/reference/APISample_linter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//// [APISample_linter.ts]
2-
32
/*
43
* Note: This test is a public API sample. The sample sources can be found
54
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
@@ -65,12 +64,12 @@ fileNames.forEach(fileName => {
6564
});
6665

6766
//// [APISample_linter.js]
67+
"use strict";
6868
/*
6969
* Note: This test is a public API sample. The sample sources can be found
7070
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
7171
* Please log a "breaking change" issue for any API breaking change affecting this issue
7272
*/
73-
"use strict";
7473
exports.__esModule = true;
7574
var ts = require("typescript");
7675
function delint(sourceFile) {

tests/baselines/reference/APISample_parseConfig.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//// [APISample_parseConfig.ts]
2-
32
/*
43
* Note: This test is a public API sample. The sample sources can be found
54
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
@@ -37,12 +36,12 @@ export function createProgram(rootFiles: string[], compilerOptionsJson: string):
3736
}
3837

3938
//// [APISample_parseConfig.js]
39+
"use strict";
4040
/*
4141
* Note: This test is a public API sample. The sample sources can be found
4242
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
4343
* Please log a "breaking change" issue for any API breaking change affecting this issue
4444
*/
45-
"use strict";
4645
exports.__esModule = true;
4746
var ts = require("typescript");
4847
function printError(error) {

0 commit comments

Comments
 (0)