Simplify deferred checking of function, class, and accessor bodies.
This commit is contained in:
parent
87036fe9f7
commit
b44f6e47d6
1 changed files with 40 additions and 115 deletions
|
@ -161,6 +161,8 @@ namespace ts {
|
|||
|
||||
let jsxElementClassType: Type;
|
||||
|
||||
let deferredNodes: Node[];
|
||||
|
||||
const tupleTypes: Map<TupleType> = {};
|
||||
const unionTypes: Map<UnionType> = {};
|
||||
const intersectionTypes: Map<IntersectionType> = {};
|
||||
|
@ -10123,6 +10125,7 @@ namespace ts {
|
|||
|
||||
if (!contextChecked) {
|
||||
checkSignatureDeclaration(node);
|
||||
checkNodeDeferred(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10135,7 +10138,7 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
|
||||
function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
const isAsync = isAsyncFunctionLike(node);
|
||||
|
@ -10178,8 +10181,6 @@ namespace ts {
|
|||
checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
|
||||
}
|
||||
}
|
||||
|
||||
checkFunctionAndClassExpressionBodies(node.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11428,13 +11429,13 @@ namespace ts {
|
|||
if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
checkSourceElement(node.body);
|
||||
}
|
||||
else {
|
||||
checkNodeDeferred(node);
|
||||
}
|
||||
}
|
||||
|
||||
function checkObjectLiteralAccessorBody(node: AccessorDeclaration) {
|
||||
if (node.body) {
|
||||
checkSourceElement(node.body);
|
||||
checkFunctionAndClassExpressionBodies(node.body);
|
||||
}
|
||||
function checkAccessorDeferred(node: AccessorDeclaration) {
|
||||
checkSourceElement(node.body);
|
||||
}
|
||||
|
||||
function checkMissingDeclaration(node: Node) {
|
||||
|
@ -12373,11 +12374,7 @@ namespace ts {
|
|||
if (node.kind === SyntaxKind.Block) {
|
||||
checkGrammarStatementInAmbientContext(node);
|
||||
}
|
||||
|
||||
forEach(node.statements, checkSourceElement);
|
||||
if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) {
|
||||
checkFunctionAndClassExpressionBodies(node);
|
||||
}
|
||||
}
|
||||
|
||||
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
|
||||
|
@ -13406,15 +13403,19 @@ namespace ts {
|
|||
|
||||
function checkClassExpression(node: ClassExpression): Type {
|
||||
checkClassLikeDeclaration(node);
|
||||
checkNodeDeferred(node);
|
||||
return getTypeOfSymbol(getSymbolOfNode(node));
|
||||
}
|
||||
|
||||
function checkClassExpressionDeferred(node: ClassExpression) {
|
||||
forEach(node.members, checkSourceElement);
|
||||
}
|
||||
|
||||
function checkClassDeclaration(node: ClassDeclaration) {
|
||||
if (!node.name && !(node.flags & NodeFlags.Default)) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
|
||||
}
|
||||
checkClassLikeDeclaration(node);
|
||||
|
||||
forEach(node.members, checkSourceElement);
|
||||
}
|
||||
|
||||
|
@ -14478,107 +14479,29 @@ namespace ts {
|
|||
// Here, performing a full type check of the body of the function expression whilst in the process of
|
||||
// determining the type of foo would cause foo to be given type any because of the recursive reference.
|
||||
// Delaying the type check of the body ensures foo has been assigned a type.
|
||||
function checkFunctionAndClassExpressionBodies(node: Node): void {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
|
||||
checkFunctionExpressionOrObjectLiteralMethodBody(<FunctionExpression>node);
|
||||
break;
|
||||
case SyntaxKind.ClassExpression:
|
||||
forEach((<ClassExpression>node).members, checkSourceElement);
|
||||
forEachChild(node, checkFunctionAndClassExpressionBodies);
|
||||
break;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
forEach(node.decorators, checkFunctionAndClassExpressionBodies);
|
||||
forEach((<MethodDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
|
||||
if (isObjectLiteralMethod(node)) {
|
||||
checkFunctionExpressionOrObjectLiteralMethodBody(node);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
|
||||
break;
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
forEach((<FunctionLikeDeclaration>node).parameters, checkFunctionAndClassExpressionBodies);
|
||||
if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
checkObjectLiteralAccessorBody(<AccessorDeclaration>node);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.WithStatement:
|
||||
checkFunctionAndClassExpressionBodies((<WithStatement>node).expression);
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.TemplateSpan:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.ContinueStatement:
|
||||
case SyntaxKind.BreakStatement:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.DefaultClause:
|
||||
case SyntaxKind.LabeledStatement:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
case SyntaxKind.TryStatement:
|
||||
case SyntaxKind.CatchClause:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.HeritageClause:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
forEachChild(node, checkFunctionAndClassExpressionBodies);
|
||||
break;
|
||||
function checkNodeDeferred(node: Node) {
|
||||
if (deferredNodes) {
|
||||
deferredNodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
function checkDeferredNodes() {
|
||||
for (const node of deferredNodes) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
checkFunctionExpressionOrObjectLiteralMethodDeferred(<FunctionExpression>node);
|
||||
break;
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
checkAccessorDeferred(<AccessorDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ClassExpression:
|
||||
checkClassExpressionDeferred(<ClassExpression>node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14613,8 +14536,10 @@ namespace ts {
|
|||
emitAwaiter = false;
|
||||
potentialThisCollisions.length = 0;
|
||||
|
||||
deferredNodes = [];
|
||||
forEach(node.statements, checkSourceElement);
|
||||
checkFunctionAndClassExpressionBodies(node);
|
||||
checkDeferredNodes();
|
||||
deferredNodes = undefined;
|
||||
|
||||
if (isExternalOrCommonJsModule(node)) {
|
||||
checkExternalModuleExports(node);
|
||||
|
|
Loading…
Reference in a new issue