mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 12:15:34 -06:00
Merge pull request #6083 from Microsoft/simplifyDeferredChecking
Simplify deferred function, class, and accessor checking
This commit is contained in:
commit
55d4f0f7e4
@ -161,6 +161,8 @@ namespace ts {
|
||||
|
||||
let jsxElementClassType: Type;
|
||||
|
||||
let deferredNodes: Node[];
|
||||
|
||||
const tupleTypes: Map<TupleType> = {};
|
||||
const unionTypes: Map<UnionType> = {};
|
||||
const intersectionTypes: Map<IntersectionType> = {};
|
||||
@ -10156,6 +10158,7 @@ namespace ts {
|
||||
|
||||
if (!contextChecked) {
|
||||
checkSignatureDeclaration(node);
|
||||
checkNodeDeferred(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10168,7 +10171,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);
|
||||
@ -10211,8 +10214,6 @@ namespace ts {
|
||||
checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
|
||||
}
|
||||
}
|
||||
|
||||
checkFunctionAndClassExpressionBodies(node.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11461,13 +11462,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) {
|
||||
@ -12406,11 +12407,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) {
|
||||
@ -13439,15 +13436,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);
|
||||
}
|
||||
|
||||
@ -14511,107 +14512,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14646,8 +14569,10 @@ namespace ts {
|
||||
emitAwaiter = false;
|
||||
potentialThisCollisions.length = 0;
|
||||
|
||||
deferredNodes = [];
|
||||
forEach(node.statements, checkSourceElement);
|
||||
checkFunctionAndClassExpressionBodies(node);
|
||||
checkDeferredNodes();
|
||||
deferredNodes = undefined;
|
||||
|
||||
if (isExternalOrCommonJsModule(node)) {
|
||||
checkExternalModuleExports(node);
|
||||
|
||||
@ -1,20 +1,11 @@
|
||||
tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body.
|
||||
tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,18): error TS2304: Cannot find name 'role'.
|
||||
tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(2,18): error TS2304: Cannot find name 'Role'.
|
||||
tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(4,26): error TS2503: Cannot find namespace 'ng'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (4 errors) ====
|
||||
==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (1 errors) ====
|
||||
return this.edit(role)
|
||||
~~~~~~
|
||||
!!! error TS1108: A 'return' statement can only be used within a function body.
|
||||
~~~~
|
||||
!!! error TS2304: Cannot find name 'role'.
|
||||
.then((role: Role) =>
|
||||
~~~~
|
||||
!!! error TS2304: Cannot find name 'Role'.
|
||||
this.roleService.add(role)
|
||||
.then((data: ng.IHttpPromiseCallbackArg<Role>) => data.data));
|
||||
~~
|
||||
!!! error TS2503: Cannot find namespace 'ng'.
|
||||
|
||||
@ -6,9 +6,8 @@ return this.edit(role)
|
||||
|
||||
|
||||
//// [multiLinePropertyAccessAndArrowFunctionIndent1.js]
|
||||
var _this = this;
|
||||
return this.edit(role)
|
||||
.then(function (role) {
|
||||
return _this.roleService.add(role)
|
||||
return this.roleService.add(role)
|
||||
.then(function (data) { return data.data; });
|
||||
});
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts(6,5): error TS2304: Cannot find name 'private'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts (2 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts (1 errors) ====
|
||||
return {
|
||||
~~~~~~
|
||||
!!! error TS1108: A 'return' statement can only be used within a function body.
|
||||
@ -11,8 +10,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMe
|
||||
|
||||
// 'private' should not be considered a member variable here.
|
||||
private[key] = value;
|
||||
~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'private'.
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user