From 88854d2c0f50ce39ef8357b0379bb1fa0d704ba5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 28 Apr 2016 13:17:06 -0700 Subject: [PATCH] Address PR comments. 1. Remove intersection code. The any-defaulting code means that it's never hit. 2. Remove some code duplication. --- src/compiler/checker.ts | 74 +++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2f3bd4b285f..7a301884b4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5508,6 +5508,10 @@ namespace ts { return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow; } + function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration { + return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); + } + function getTypeWithoutSignatures(type: Type): Type { if (type.flags & TypeFlags.ObjectType) { const resolved = resolveStructuredTypeMembers(type); @@ -8205,13 +8209,9 @@ namespace ts { if (container.parent && container.parent.kind === SyntaxKind.ObjectLiteralExpression) { // Note: this works because object literal methods are deferred, // which means that the type of the containing object literal is already known. - const contextualType = getContextualType(container.parent as ObjectLiteralExpression); - const literalType = checkExpressionCached(container.parent); - if (contextualType && literalType) { - return getIntersectionType([contextualType, literalType]); - } - else if (contextualType || literalType) { - return contextualType || literalType; + const type = checkExpressionCached(container.parent); + if (type) { + return type; } } } @@ -8450,19 +8450,14 @@ namespace ts { } function getContextuallyTypedThisType(func: FunctionLikeDeclaration): Type { - if ((isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && - isContextSensitive(func) && - func.kind !== SyntaxKind.ArrowFunction) { - const type = isObjectLiteralMethod(func) - ? getContextualTypeForObjectLiteralMethod(func) - : getApparentTypeOfContextualType(func); - if (type === anyType) { - return anyType; - } + if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) { const contextualSignature = getContextualSignature(func); if (contextualSignature) { return contextualSignature.thisType; } + else if (getContextualTypeForFunctionLikeDeclaration(func) === anyType) { + return anyType; + } } return undefined; @@ -8471,24 +8466,21 @@ namespace ts { // Return contextual type of parameter or undefined if no contextual type is available function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type { const func = parameter.parent; - if (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) { - if (isContextSensitive(func)) { - const contextualSignature = getContextualSignature(func); - if (contextualSignature) { + if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { + const contextualSignature = getContextualSignature(func); + if (contextualSignature) { + const funcHasRestParameters = hasRestParameter(func); + const len = func.parameters.length - (funcHasRestParameters ? 1 : 0); + const indexOfParameter = indexOf(func.parameters, parameter); + if (indexOfParameter < len) { + return getTypeAtPosition(contextualSignature, indexOfParameter); + } - const funcHasRestParameters = hasRestParameter(func); - const len = func.parameters.length - (funcHasRestParameters ? 1 : 0); - const indexOfParameter = indexOf(func.parameters, parameter); - if (indexOfParameter < len) { - return getTypeAtPosition(contextualSignature, indexOfParameter); - } - - // If last parameter is contextually rest parameter get its type - if (funcHasRestParameters && - indexOfParameter === (func.parameters.length - 1) && - isRestParameterIndex(contextualSignature, func.parameters.length - 1)) { - return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters)); - } + // If last parameter is contextually rest parameter get its type + if (funcHasRestParameters && + indexOfParameter === (func.parameters.length - 1) && + isRestParameterIndex(contextualSignature, func.parameters.length - 1)) { + return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters)); } } } @@ -8496,9 +8488,9 @@ namespace ts { } // In a variable, parameter or property declaration with a type annotation, - // the contextual type of an initializer expression is the type of the variable, parameter or property. - // Otherwise, in a parameter declaration of a contextually typed function expression, - // the contextual type of an initializer expression is the contextual type of the parameter. + // the contextual type of an initializer expression is the type of the variable, parameter or property. + // Otherwise, in a parameter declaration of a contextually typed function expression, + // the contextual type of an initializer expression is the contextual type of the parameter. // Otherwise, in a variable or parameter declaration with a binding pattern name, // the contextual type of an initializer expression is the type implied by the binding pattern. // Otherwise, in a binding pattern inside a variable or parameter declaration, @@ -8852,6 +8844,12 @@ namespace ts { : undefined; } + function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) { + return isObjectLiteralMethod(node) + ? getContextualTypeForObjectLiteralMethod(node) + : getApparentTypeOfContextualType(node); + } + // Return the contextual signature for a given expression node. A contextual type provides a // contextual signature if it has a single call signature and if that call signature is non-generic. // If the contextual type is a union type, get the signature from each type possible and if they are @@ -8859,9 +8857,7 @@ namespace ts { // union type of return types from these signatures function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); - const type = isObjectLiteralMethod(node) - ? getContextualTypeForObjectLiteralMethod(node) - : getApparentTypeOfContextualType(node); + const type = getContextualTypeForFunctionLikeDeclaration(node); if (!type) { return undefined; }