@@ -161,6 +161,8 @@ namespace ts {
161161
162162 let jsxElementClassType: Type;
163163
164+ let deferredNodes: Node[];
165+
164166 const tupleTypes: Map<TupleType> = {};
165167 const unionTypes: Map<UnionType> = {};
166168 const intersectionTypes: Map<IntersectionType> = {};
@@ -10156,6 +10158,7 @@ namespace ts {
1015610158
1015710159 if (!contextChecked) {
1015810160 checkSignatureDeclaration(node);
10161+ checkNodeDeferred(node);
1015910162 }
1016010163 }
1016110164 }
@@ -10168,7 +10171,7 @@ namespace ts {
1016810171 return type;
1016910172 }
1017010173
10171- function checkFunctionExpressionOrObjectLiteralMethodBody (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
10174+ function checkFunctionExpressionOrObjectLiteralMethodDeferred (node: ArrowFunction | FunctionExpression | MethodDeclaration) {
1017210175 Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
1017310176
1017410177 const isAsync = isAsyncFunctionLike(node);
@@ -10211,8 +10214,6 @@ namespace ts {
1021110214 checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
1021210215 }
1021310216 }
10214-
10215- checkFunctionAndClassExpressionBodies(node.body);
1021610217 }
1021710218 }
1021810219 }
@@ -11461,13 +11462,13 @@ namespace ts {
1146111462 if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
1146211463 checkSourceElement(node.body);
1146311464 }
11465+ else {
11466+ checkNodeDeferred(node);
11467+ }
1146411468 }
1146511469
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);
1147111472 }
1147211473
1147311474 function checkMissingDeclaration(node: Node) {
@@ -12406,11 +12407,7 @@ namespace ts {
1240612407 if (node.kind === SyntaxKind.Block) {
1240712408 checkGrammarStatementInAmbientContext(node);
1240812409 }
12409-
1241012410 forEach(node.statements, checkSourceElement);
12411- if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) {
12412- checkFunctionAndClassExpressionBodies(node);
12413- }
1241412411 }
1241512412
1241612413 function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
@@ -13439,15 +13436,19 @@ namespace ts {
1343913436
1344013437 function checkClassExpression(node: ClassExpression): Type {
1344113438 checkClassLikeDeclaration(node);
13439+ checkNodeDeferred(node);
1344213440 return getTypeOfSymbol(getSymbolOfNode(node));
1344313441 }
1344413442
13443+ function checkClassExpressionDeferred(node: ClassExpression) {
13444+ forEach(node.members, checkSourceElement);
13445+ }
13446+
1344513447 function checkClassDeclaration(node: ClassDeclaration) {
1344613448 if (!node.name && !(node.flags & NodeFlags.Default)) {
1344713449 grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
1344813450 }
1344913451 checkClassLikeDeclaration(node);
13450-
1345113452 forEach(node.members, checkSourceElement);
1345213453 }
1345313454
@@ -14511,107 +14512,29 @@ namespace ts {
1451114512 // Here, performing a full type check of the body of the function expression whilst in the process of
1451214513 // determining the type of foo would cause foo to be given type any because of the recursive reference.
1451314514 // 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+ }
1461514538 }
1461614539 }
1461714540
@@ -14646,8 +14569,10 @@ namespace ts {
1464614569 emitAwaiter = false;
1464714570 potentialThisCollisions.length = 0;
1464814571
14572+ deferredNodes = [];
1464914573 forEach(node.statements, checkSourceElement);
14650- checkFunctionAndClassExpressionBodies(node);
14574+ checkDeferredNodes();
14575+ deferredNodes = undefined;
1465114576
1465214577 if (isExternalOrCommonJsModule(node)) {
1465314578 checkExternalModuleExports(node);
0 commit comments