@@ -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> = {};
@@ -10123,6 +10125,7 @@ namespace ts {
10123
10125
10124
10126
if (!contextChecked) {
10125
10127
checkSignatureDeclaration(node);
10128
+ checkNodeDeferred(node);
10126
10129
}
10127
10130
}
10128
10131
}
@@ -10135,7 +10138,7 @@ namespace ts {
10135
10138
return type;
10136
10139
}
10137
10140
10138
- function checkFunctionExpressionOrObjectLiteralMethodBody (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
10141
+ function checkFunctionExpressionOrObjectLiteralMethodDeferred (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
10139
10142
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
10140
10143
10141
10144
const isAsync = isAsyncFunctionLike(node);
@@ -10178,8 +10181,6 @@ namespace ts {
10178
10181
checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
10179
10182
}
10180
10183
}
10181
-
10182
- checkFunctionAndClassExpressionBodies(node.body);
10183
10184
}
10184
10185
}
10185
10186
}
@@ -11428,13 +11429,13 @@ namespace ts {
11428
11429
if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
11429
11430
checkSourceElement(node.body);
11430
11431
}
11432
+ else {
11433
+ checkNodeDeferred(node);
11434
+ }
11431
11435
}
11432
11436
11433
- function checkObjectLiteralAccessorBody(node: AccessorDeclaration) {
11434
- if (node.body) {
11435
- checkSourceElement(node.body);
11436
- checkFunctionAndClassExpressionBodies(node.body);
11437
- }
11437
+ function checkAccessorDeferred(node: AccessorDeclaration) {
11438
+ checkSourceElement(node.body);
11438
11439
}
11439
11440
11440
11441
function checkMissingDeclaration(node: Node) {
@@ -12373,11 +12374,7 @@ namespace ts {
12373
12374
if (node.kind === SyntaxKind.Block) {
12374
12375
checkGrammarStatementInAmbientContext(node);
12375
12376
}
12376
-
12377
12377
forEach(node.statements, checkSourceElement);
12378
- if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) {
12379
- checkFunctionAndClassExpressionBodies(node);
12380
- }
12381
12378
}
12382
12379
12383
12380
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
@@ -13406,15 +13403,19 @@ namespace ts {
13406
13403
13407
13404
function checkClassExpression(node: ClassExpression): Type {
13408
13405
checkClassLikeDeclaration(node);
13406
+ checkNodeDeferred(node);
13409
13407
return getTypeOfSymbol(getSymbolOfNode(node));
13410
13408
}
13411
13409
13410
+ function checkClassExpressionDeferred(node: ClassExpression) {
13411
+ forEach(node.members, checkSourceElement);
13412
+ }
13413
+
13412
13414
function checkClassDeclaration(node: ClassDeclaration) {
13413
13415
if (!node.name && !(node.flags & NodeFlags.Default)) {
13414
13416
grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
13415
13417
}
13416
13418
checkClassLikeDeclaration(node);
13417
-
13418
13419
forEach(node.members, checkSourceElement);
13419
13420
}
13420
13421
@@ -14478,107 +14479,29 @@ namespace ts {
14478
14479
// Here, performing a full type check of the body of the function expression whilst in the process of
14479
14480
// determining the type of foo would cause foo to be given type any because of the recursive reference.
14480
14481
// Delaying the type check of the body ensures foo has been assigned a type.
14481
- function checkFunctionAndClassExpressionBodies(node: Node): void {
14482
- switch (node.kind) {
14483
- case SyntaxKind.FunctionExpression:
14484
- case SyntaxKind.ArrowFunction:
14485
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14486
- checkFunctionExpressionOrObjectLiteralMethodBody(<FunctionExpression>node);
14487
- break;
14488
- case SyntaxKind.ClassExpression:
14489
- forEach((<ClassExpression>node).members, checkSourceElement);
14490
- forEachChild(node, checkFunctionAndClassExpressionBodies);
14491
- break;
14492
- case SyntaxKind.MethodDeclaration:
14493
- case SyntaxKind.MethodSignature:
14494
- forEach(node.decorators, checkFunctionAndClassExpressionBodies);
14495
- forEach((<MethodDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14496
- if (isObjectLiteralMethod(node)) {
14497
- checkFunctionExpressionOrObjectLiteralMethodBody(node);
14498
- }
14499
- break;
14500
- case SyntaxKind.Constructor:
14501
- case SyntaxKind.FunctionDeclaration:
14502
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14503
- break;
14504
- case SyntaxKind.GetAccessor:
14505
- case SyntaxKind.SetAccessor:
14506
- forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
14507
- if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) {
14508
- checkObjectLiteralAccessorBody(<AccessorDeclaration>node);
14509
- }
14510
- break;
14511
- case SyntaxKind.WithStatement:
14512
- checkFunctionAndClassExpressionBodies((<WithStatement>node).expression);
14513
- break;
14514
- case SyntaxKind.Decorator:
14515
- case SyntaxKind.Parameter:
14516
- case SyntaxKind.PropertyDeclaration:
14517
- case SyntaxKind.PropertySignature:
14518
- case SyntaxKind.ObjectBindingPattern:
14519
- case SyntaxKind.ArrayBindingPattern:
14520
- case SyntaxKind.BindingElement:
14521
- case SyntaxKind.ArrayLiteralExpression:
14522
- case SyntaxKind.ObjectLiteralExpression:
14523
- case SyntaxKind.PropertyAssignment:
14524
- case SyntaxKind.PropertyAccessExpression:
14525
- case SyntaxKind.ElementAccessExpression:
14526
- case SyntaxKind.CallExpression:
14527
- case SyntaxKind.NewExpression:
14528
- case SyntaxKind.TaggedTemplateExpression:
14529
- case SyntaxKind.TemplateExpression:
14530
- case SyntaxKind.TemplateSpan:
14531
- case SyntaxKind.TypeAssertionExpression:
14532
- case SyntaxKind.AsExpression:
14533
- case SyntaxKind.ParenthesizedExpression:
14534
- case SyntaxKind.TypeOfExpression:
14535
- case SyntaxKind.VoidExpression:
14536
- case SyntaxKind.AwaitExpression:
14537
- case SyntaxKind.DeleteExpression:
14538
- case SyntaxKind.PrefixUnaryExpression:
14539
- case SyntaxKind.PostfixUnaryExpression:
14540
- case SyntaxKind.BinaryExpression:
14541
- case SyntaxKind.ConditionalExpression:
14542
- case SyntaxKind.SpreadElementExpression:
14543
- case SyntaxKind.YieldExpression:
14544
- case SyntaxKind.Block:
14545
- case SyntaxKind.ModuleBlock:
14546
- case SyntaxKind.VariableStatement:
14547
- case SyntaxKind.ExpressionStatement:
14548
- case SyntaxKind.IfStatement:
14549
- case SyntaxKind.DoStatement:
14550
- case SyntaxKind.WhileStatement:
14551
- case SyntaxKind.ForStatement:
14552
- case SyntaxKind.ForInStatement:
14553
- case SyntaxKind.ForOfStatement:
14554
- case SyntaxKind.ContinueStatement:
14555
- case SyntaxKind.BreakStatement:
14556
- case SyntaxKind.ReturnStatement:
14557
- case SyntaxKind.SwitchStatement:
14558
- case SyntaxKind.CaseBlock:
14559
- case SyntaxKind.CaseClause:
14560
- case SyntaxKind.DefaultClause:
14561
- case SyntaxKind.LabeledStatement:
14562
- case SyntaxKind.ThrowStatement:
14563
- case SyntaxKind.TryStatement:
14564
- case SyntaxKind.CatchClause:
14565
- case SyntaxKind.VariableDeclaration:
14566
- case SyntaxKind.VariableDeclarationList:
14567
- case SyntaxKind.ClassDeclaration:
14568
- case SyntaxKind.HeritageClause:
14569
- case SyntaxKind.ExpressionWithTypeArguments:
14570
- case SyntaxKind.EnumDeclaration:
14571
- case SyntaxKind.EnumMember:
14572
- case SyntaxKind.ExportAssignment:
14573
- case SyntaxKind.SourceFile:
14574
- case SyntaxKind.JsxExpression:
14575
- case SyntaxKind.JsxElement:
14576
- case SyntaxKind.JsxSelfClosingElement:
14577
- case SyntaxKind.JsxAttribute:
14578
- case SyntaxKind.JsxSpreadAttribute:
14579
- case SyntaxKind.JsxOpeningElement:
14580
- forEachChild(node, checkFunctionAndClassExpressionBodies);
14581
- break;
14482
+ function checkNodeDeferred(node: Node) {
14483
+ if (deferredNodes) {
14484
+ deferredNodes.push(node);
14485
+ }
14486
+ }
14487
+
14488
+ function checkDeferredNodes() {
14489
+ for (const node of deferredNodes) {
14490
+ switch (node.kind) {
14491
+ case SyntaxKind.FunctionExpression:
14492
+ case SyntaxKind.ArrowFunction:
14493
+ case SyntaxKind.MethodDeclaration:
14494
+ case SyntaxKind.MethodSignature:
14495
+ checkFunctionExpressionOrObjectLiteralMethodDeferred(<FunctionExpression>node);
14496
+ break;
14497
+ case SyntaxKind.GetAccessor:
14498
+ case SyntaxKind.SetAccessor:
14499
+ checkAccessorDeferred(<AccessorDeclaration>node);
14500
+ break;
14501
+ case SyntaxKind.ClassExpression:
14502
+ checkClassExpressionDeferred(<ClassExpression>node);
14503
+ break;
14504
+ }
14582
14505
}
14583
14506
}
14584
14507
@@ -14613,8 +14536,10 @@ namespace ts {
14613
14536
emitAwaiter = false;
14614
14537
potentialThisCollisions.length = 0;
14615
14538
14539
+ deferredNodes = [];
14616
14540
forEach(node.statements, checkSourceElement);
14617
- checkFunctionAndClassExpressionBodies(node);
14541
+ checkDeferredNodes();
14542
+ deferredNodes = undefined;
14618
14543
14619
14544
if (isExternalOrCommonJsModule(node)) {
14620
14545
checkExternalModuleExports(node);
0 commit comments