@@ -161,6 +161,8 @@ namespace ts {
161
161
162
162
let jsxElementClassType: Type;
163
163
164
+ let deferredNodes: Node[];
165
+
164
166
const tupleTypes: Map<TupleType> = {};
165
167
const unionTypes: Map<UnionType> = {};
166
168
const intersectionTypes: Map<IntersectionType> = {};
@@ -10156,6 +10158,7 @@ namespace ts {
10156
10158
10157
10159
if (!contextChecked) {
10158
10160
checkSignatureDeclaration(node);
10161
+ checkNodeDeferred(node);
10159
10162
}
10160
10163
}
10161
10164
}
@@ -10168,7 +10171,7 @@ namespace ts {
10168
10171
return type;
10169
10172
}
10170
10173
10171
- function checkFunctionExpressionOrObjectLiteralMethodBody (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
10174
+ function checkFunctionExpressionOrObjectLiteralMethodDeferred (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
10172
10175
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
10173
10176
10174
10177
const isAsync = isAsyncFunctionLike(node);
@@ -10211,8 +10214,6 @@ namespace ts {
10211
10214
checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
10212
10215
}
10213
10216
}
10214
-
10215
- checkFunctionAndClassExpressionBodies(node.body);
10216
10217
}
10217
10218
}
10218
10219
}
@@ -11461,13 +11462,13 @@ namespace ts {
11461
11462
if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
11462
11463
checkSourceElement(node.body);
11463
11464
}
11465
+ else {
11466
+ checkNodeDeferred(node);
11467
+ }
11464
11468
}
11465
11469
11466
- function checkObjectLiteralAccessorBody(node: AccessorDeclaration) {
11467
- if (node.body) {
11468
- checkSourceElement(node.body);
11469
- checkFunctionAndClassExpressionBodies(node.body);
11470
- }
11470
+ function checkAccessorDeferred(node: AccessorDeclaration) {
11471
+ checkSourceElement(node.body);
11471
11472
}
11472
11473
11473
11474
function checkMissingDeclaration(node: Node) {
@@ -12406,11 +12407,7 @@ namespace ts {
12406
12407
if (node.kind === SyntaxKind.Block) {
12407
12408
checkGrammarStatementInAmbientContext(node);
12408
12409
}
12409
-
12410
12410
forEach(node.statements, checkSourceElement);
12411
- if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) {
12412
- checkFunctionAndClassExpressionBodies(node);
12413
- }
12414
12411
}
12415
12412
12416
12413
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
@@ -13439,15 +13436,19 @@ namespace ts {
13439
13436
13440
13437
function checkClassExpression(node: ClassExpression): Type {
13441
13438
checkClassLikeDeclaration(node);
13439
+ checkNodeDeferred(node);
13442
13440
return getTypeOfSymbol(getSymbolOfNode(node));
13443
13441
}
13444
13442
13443
+ function checkClassExpressionDeferred(node: ClassExpression) {
13444
+ forEach(node.members, checkSourceElement);
13445
+ }
13446
+
13445
13447
function checkClassDeclaration(node: ClassDeclaration) {
13446
13448
if (!node.name && !(node.flags & NodeFlags.Default)) {
13447
13449
grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
13448
13450
}
13449
13451
checkClassLikeDeclaration(node);
13450
-
13451
13452
forEach(node.members, checkSourceElement);
13452
13453
}
13453
13454
@@ -14511,107 +14512,29 @@ namespace ts {
14511
14512
// Here, performing a full type check of the body of the function expression whilst in the process of
14512
14513
// determining the type of foo would cause foo to be given type any because of the recursive reference.
14513
14514
// Delaying the type check of the body ensures foo has been assigned a type.
14514
- function checkFunctionAndClassExpressionBodies(node: Node): void {
14515
- switch (node.kind) {
14516
- case SyntaxKind.FunctionExpression:
14517
- case SyntaxKind.ArrowFunction:
14518
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14519
- checkFunctionExpressionOrObjectLiteralMethodBody(<FunctionExpression>node);
14520
- break;
14521
- case SyntaxKind.ClassExpression:
14522
- forEach((<ClassExpression>node).members, checkSourceElement);
14523
- forEachChild(node, checkFunctionAndClassExpressionBodies);
14524
- break;
14525
- case SyntaxKind.MethodDeclaration:
14526
- case SyntaxKind.MethodSignature:
14527
- forEach(node.decorators, checkFunctionAndClassExpressionBodies);
14528
- forEach((<MethodDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14529
- if (isObjectLiteralMethod(node)) {
14530
- checkFunctionExpressionOrObjectLiteralMethodBody(node);
14531
- }
14532
- break;
14533
- case SyntaxKind.Constructor:
14534
- case SyntaxKind.FunctionDeclaration:
14535
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14536
- break;
14537
- case SyntaxKind.GetAccessor:
14538
- case SyntaxKind.SetAccessor:
14539
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14540
- if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) {
14541
- checkObjectLiteralAccessorBody(<AccessorDeclaration>node);
14542
- }
14543
- break;
14544
- case SyntaxKind.WithStatement:
14545
- checkFunctionAndClassExpressionBodies((<WithStatement>node).expression);
14546
- break;
14547
- case SyntaxKind.Decorator:
14548
- case SyntaxKind.Parameter:
14549
- case SyntaxKind.PropertyDeclaration:
14550
- case SyntaxKind.PropertySignature:
14551
- case SyntaxKind.ObjectBindingPattern:
14552
- case SyntaxKind.ArrayBindingPattern:
14553
- case SyntaxKind.BindingElement:
14554
- case SyntaxKind.ArrayLiteralExpression:
14555
- case SyntaxKind.ObjectLiteralExpression:
14556
- case SyntaxKind.PropertyAssignment:
14557
- case SyntaxKind.PropertyAccessExpression:
14558
- case SyntaxKind.ElementAccessExpression:
14559
- case SyntaxKind.CallExpression:
14560
- case SyntaxKind.NewExpression:
14561
- case SyntaxKind.TaggedTemplateExpression:
14562
- case SyntaxKind.TemplateExpression:
14563
- case SyntaxKind.TemplateSpan:
14564
- case SyntaxKind.TypeAssertionExpression:
14565
- case SyntaxKind.AsExpression:
14566
- case SyntaxKind.ParenthesizedExpression:
14567
- case SyntaxKind.TypeOfExpression:
14568
- case SyntaxKind.VoidExpression:
14569
- case SyntaxKind.AwaitExpression:
14570
- case SyntaxKind.DeleteExpression:
14571
- case SyntaxKind.PrefixUnaryExpression:
14572
- case SyntaxKind.PostfixUnaryExpression:
14573
- case SyntaxKind.BinaryExpression:
14574
- case SyntaxKind.ConditionalExpression:
14575
- case SyntaxKind.SpreadElementExpression:
14576
- case SyntaxKind.YieldExpression:
14577
- case SyntaxKind.Block:
14578
- case SyntaxKind.ModuleBlock:
14579
- case SyntaxKind.VariableStatement:
14580
- case SyntaxKind.ExpressionStatement:
14581
- case SyntaxKind.IfStatement:
14582
- case SyntaxKind.DoStatement:
14583
- case SyntaxKind.WhileStatement:
14584
- case SyntaxKind.ForStatement:
14585
- case SyntaxKind.ForInStatement:
14586
- case SyntaxKind.ForOfStatement:
14587
- case SyntaxKind.ContinueStatement:
14588
- case SyntaxKind.BreakStatement:
14589
- case SyntaxKind.ReturnStatement:
14590
- case SyntaxKind.SwitchStatement:
14591
- case SyntaxKind.CaseBlock:
14592
- case SyntaxKind.CaseClause:
14593
- case SyntaxKind.DefaultClause:
14594
- case SyntaxKind.LabeledStatement:
14595
- case SyntaxKind.ThrowStatement:
14596
- case SyntaxKind.TryStatement:
14597
- case SyntaxKind.CatchClause:
14598
- case SyntaxKind.VariableDeclaration:
14599
- case SyntaxKind.VariableDeclarationList:
14600
- case SyntaxKind.ClassDeclaration:
14601
- case SyntaxKind.HeritageClause:
14602
- case SyntaxKind.ExpressionWithTypeArguments:
14603
- case SyntaxKind.EnumDeclaration:
14604
- case SyntaxKind.EnumMember:
14605
- case SyntaxKind.ExportAssignment:
14606
- case SyntaxKind.SourceFile:
14607
- case SyntaxKind.JsxExpression:
14608
- case SyntaxKind.JsxElement:
14609
- case SyntaxKind.JsxSelfClosingElement:
14610
- case SyntaxKind.JsxAttribute:
14611
- case SyntaxKind.JsxSpreadAttribute:
14612
- case SyntaxKind.JsxOpeningElement:
14613
- forEachChild(node, checkFunctionAndClassExpressionBodies);
14614
- break;
14515
+ function checkNodeDeferred(node: Node) {
14516
+ if (deferredNodes) {
14517
+ deferredNodes.push(node);
14518
+ }
14519
+ }
14520
+
14521
+ function checkDeferredNodes() {
14522
+ for (const node of deferredNodes) {
14523
+ switch (node.kind) {
14524
+ case SyntaxKind.FunctionExpression:
14525
+ case SyntaxKind.ArrowFunction:
14526
+ case SyntaxKind.MethodDeclaration:
14527
+ case SyntaxKind.MethodSignature:
14528
+ checkFunctionExpressionOrObjectLiteralMethodDeferred(<FunctionExpression>node);
14529
+ break;
14530
+ case SyntaxKind.GetAccessor:
14531
+ case SyntaxKind.SetAccessor:
14532
+ checkAccessorDeferred(<AccessorDeclaration>node);
14533
+ break;
14534
+ case SyntaxKind.ClassExpression:
14535
+ checkClassExpressionDeferred(<ClassExpression>node);
14536
+ break;
14537
+ }
14615
14538
}
14616
14539
}
14617
14540
@@ -14646,8 +14569,10 @@ namespace ts {
14646
14569
emitAwaiter = false;
14647
14570
potentialThisCollisions.length = 0;
14648
14571
14572
+ deferredNodes = [];
14649
14573
forEach(node.statements, checkSourceElement);
14650
- checkFunctionAndClassExpressionBodies(node);
14574
+ checkDeferredNodes();
14575
+ deferredNodes = undefined;
14651
14576
14652
14577
if (isExternalOrCommonJsModule(node)) {
14653
14578
checkExternalModuleExports(node);
0 commit comments