Skip to content

Commit 52a0b4b

Browse files
author
Andy Hanson
committed
Merge branch 'master' into completionsRecommended
2 parents 8918891 + 8f1cdc9 commit 52a0b4b

File tree

281 files changed

+22470
-2524
lines changed

Some content is hidden

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

281 files changed

+22470
-2524
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ tests/cases/user/*/**/*.d.ts
6767
!tests/cases/user/zone.js/
6868
!tests/cases/user/bignumber.js/
6969
!tests/cases/user/discord.js/
70+
tests/baselines/reference/dt

lib/typescript.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,9 +4487,9 @@ declare namespace ts {
44874487
* @param compilationSettings Some compilation settings like target affects the
44884488
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
44894489
* multiple copies of the same file for different compilation settings.
4490-
* @parm scriptSnapshot Text of the file. Only used if the file was not found
4490+
* @param scriptSnapshot Text of the file. Only used if the file was not found
44914491
* in the registry and a new one was created.
4492-
* @parm version Current version of the file. Only used if the file was not found
4492+
* @param version Current version of the file. Only used if the file was not found
44934493
* in the registry and a new one was created.
44944494
*/
44954495
acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile;

lib/typescriptServices.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,9 +4487,9 @@ declare namespace ts {
44874487
* @param compilationSettings Some compilation settings like target affects the
44884488
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
44894489
* multiple copies of the same file for different compilation settings.
4490-
* @parm scriptSnapshot Text of the file. Only used if the file was not found
4490+
* @param scriptSnapshot Text of the file. Only used if the file was not found
44914491
* in the registry and a new one was created.
4492-
* @parm version Current version of the file. Only used if the file was not found
4492+
* @param version Current version of the file. Only used if the file was not found
44934493
* in the registry and a new one was created.
44944494
*/
44954495
acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile;

src/compiler/binder.ts

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -517,16 +517,15 @@ namespace ts {
517517
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
518518
// A non-async IIFE is considered part of the containing control flow. Return statements behave
519519
// similarly to break statements that exit to a label just past the statement body.
520-
if (isIIFE) {
521-
currentReturnTarget = createBranchLabel();
522-
}
523-
else {
520+
if (!isIIFE) {
524521
currentFlow = { flags: FlowFlags.Start };
525522
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
526523
(<FlowStart>currentFlow).container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
527524
}
528-
currentReturnTarget = undefined;
529525
}
526+
// We create a return control flow graph for IIFEs and constructors. For constructors
527+
// we use the return control flow graph in strict property intialization checks.
528+
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
530529
currentBreakTarget = undefined;
531530
currentContinueTarget = undefined;
532531
activeLabels = undefined;
@@ -541,11 +540,14 @@ namespace ts {
541540
if (node.kind === SyntaxKind.SourceFile) {
542541
node.flags |= emitFlags;
543542
}
544-
if (isIIFE) {
543+
if (currentReturnTarget) {
545544
addAntecedent(currentReturnTarget, currentFlow);
546545
currentFlow = finishFlowLabel(currentReturnTarget);
546+
if (node.kind === SyntaxKind.Constructor) {
547+
(<ConstructorDeclaration>node).returnFlowNode = currentFlow;
548+
}
547549
}
548-
else {
550+
if (!isIIFE) {
549551
currentFlow = saveCurrentFlow;
550552
}
551553
currentBreakTarget = saveBreakTarget;
@@ -2004,6 +2006,9 @@ namespace ts {
20042006
if (currentFlow && isNarrowableReference(<Expression>node)) {
20052007
node.flowNode = currentFlow;
20062008
}
2009+
if (isSpecialPropertyDeclaration(node as PropertyAccessExpression)) {
2010+
bindSpecialPropertyDeclaration(node as PropertyAccessExpression);
2011+
}
20072012
break;
20082013
case SyntaxKind.BinaryExpression:
20092014
const specialKind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
@@ -2312,7 +2317,7 @@ namespace ts {
23122317
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule, SymbolFlags.None);
23132318
}
23142319

2315-
function bindThisPropertyAssignment(node: BinaryExpression) {
2320+
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
23162321
Debug.assert(isInJavaScriptFile(node));
23172322
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
23182323
switch (container.kind) {
@@ -2338,8 +2343,19 @@ namespace ts {
23382343
}
23392344
}
23402345

2346+
function bindSpecialPropertyDeclaration(node: PropertyAccessExpression) {
2347+
Debug.assert(isInJavaScriptFile(node));
2348+
if (node.expression.kind === SyntaxKind.ThisKeyword) {
2349+
bindThisPropertyAssignment(node);
2350+
}
2351+
else if ((node.expression.kind === SyntaxKind.Identifier || node.expression.kind === SyntaxKind.PropertyAccessExpression) &&
2352+
node.parent.parent.kind === SyntaxKind.SourceFile) {
2353+
bindStaticPropertyAssignment(node);
2354+
}
2355+
}
2356+
23412357
function bindPrototypePropertyAssignment(node: BinaryExpression) {
2342-
// We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x was a function.
2358+
// We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x is a function or class, or not declared.
23432359

23442360
// Look up the function in the local scope, since prototype assignments should
23452361
// follow the function declaration
@@ -2355,24 +2371,27 @@ namespace ts {
23552371
bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
23562372
}
23572373

2358-
function bindStaticPropertyAssignment(node: BinaryExpression) {
2359-
// We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function.
2360-
2361-
// Look up the function in the local scope, since prototype assignments should
2374+
/**
2375+
* For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function or class, or not declared.
2376+
* Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y;
2377+
*/
2378+
function bindStaticPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
2379+
// Look up the function in the local scope, since static assignments should
23622380
// follow the function declaration
2363-
const leftSideOfAssignment = node.left as PropertyAccessExpression;
2381+
const leftSideOfAssignment = node.kind === SyntaxKind.PropertyAccessExpression ? node : node.left as PropertyAccessExpression;
23642382
const target = leftSideOfAssignment.expression;
23652383

23662384
if (isIdentifier(target)) {
23672385
// Fix up parent pointers since we're going to use these nodes before we bind into them
2368-
leftSideOfAssignment.parent = node;
23692386
target.parent = leftSideOfAssignment;
2370-
2387+
if (node.kind === SyntaxKind.BinaryExpression) {
2388+
leftSideOfAssignment.parent = node;
2389+
}
23712390
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
23722391
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
23732392
// var util = module.exports;
23742393
// util.property = function ...
2375-
bindExportsPropertyAssignment(node);
2394+
bindExportsPropertyAssignment(node as BinaryExpression);
23762395
}
23772396
else {
23782397
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
@@ -2381,17 +2400,41 @@ namespace ts {
23812400
}
23822401

23832402
function lookupSymbolForName(name: __String) {
2384-
return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
2403+
const local = container.locals && container.locals.get(name);
2404+
if (local) {
2405+
return local.exportSymbol || local;
2406+
}
2407+
return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
23852408
}
23862409

2387-
function bindPropertyAssignment(functionName: __String, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
2388-
let targetSymbol = lookupSymbolForName(functionName);
2389-
2390-
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
2391-
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
2410+
function bindPropertyAssignment(functionName: __String, propertyAccess: PropertyAccessExpression, isPrototypeProperty: boolean) {
2411+
const symbol = lookupSymbolForName(functionName);
2412+
let targetSymbol = symbol && isDeclarationOfFunctionOrClassExpression(symbol) ?
2413+
(symbol.valueDeclaration as VariableDeclaration).initializer.symbol :
2414+
symbol;
2415+
Debug.assert(propertyAccess.parent.kind === SyntaxKind.BinaryExpression || propertyAccess.parent.kind === SyntaxKind.ExpressionStatement);
2416+
let isLegalPosition: boolean;
2417+
if (propertyAccess.parent.kind === SyntaxKind.BinaryExpression) {
2418+
const initializerKind = (propertyAccess.parent as BinaryExpression).right.kind;
2419+
isLegalPosition = (initializerKind === SyntaxKind.ClassExpression || initializerKind === SyntaxKind.FunctionExpression) &&
2420+
propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile;
23922421
}
2393-
2394-
if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class))) {
2422+
else {
2423+
isLegalPosition = propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
2424+
}
2425+
if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace)) && isLegalPosition) {
2426+
Debug.assert(isIdentifier(propertyAccess.expression));
2427+
const identifier = propertyAccess.expression as Identifier;
2428+
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
2429+
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
2430+
if (targetSymbol) {
2431+
addDeclarationToSymbol(symbol, identifier, flags);
2432+
}
2433+
else {
2434+
targetSymbol = declareSymbol(container.locals, /*parent*/ undefined, identifier, flags, excludeFlags);
2435+
}
2436+
}
2437+
if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule))) {
23952438
return;
23962439
}
23972440

@@ -2401,7 +2444,7 @@ namespace ts {
24012444
(targetSymbol.exports || (targetSymbol.exports = createSymbolTable()));
24022445

24032446
// Declare the method/property
2404-
declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
2447+
declareSymbol(symbolTable, targetSymbol, propertyAccess, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
24052448
}
24062449

24072450
function bindCallExpression(node: CallExpression) {

0 commit comments

Comments
 (0)