mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Address issue where we were having to double cast between FunctionLikeDeclaration and Expression types.
Provide brands in a few more places. Anywhere where we have a type that extends another, but only adds optional properties, we should consider brands. Stop SignatureDeclarations from being ClassElements. Instead, only IndexSignatureDeclaration is considered to be a ClassElement.
This commit is contained in:
parent
7cc65ca73e
commit
db2bf0a309
@ -4727,11 +4727,10 @@ module ts {
|
||||
|
||||
// Return contextual type of parameter or undefined if no contextual type is available
|
||||
function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type {
|
||||
var func = <FunctionLikeDeclaration>parameter.parent;
|
||||
if (func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction) {
|
||||
var funcExpr = <Expression>parameter.parent;
|
||||
if (isContextSensitiveExpression(funcExpr)) {
|
||||
var contextualSignature = getContextualSignature(funcExpr);
|
||||
if (isFunctionExpressionOrArrowFunction(parameter.parent)) {
|
||||
var func = <FunctionExpression>parameter.parent;
|
||||
if (isContextSensitiveExpression(func)) {
|
||||
var contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
|
||||
var funcHasRestParameters = hasRestParameters(func);
|
||||
@ -4779,7 +4778,7 @@ module ts {
|
||||
}
|
||||
// Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
|
||||
// and that call signature is non-generic, return statements are contextually typed by the return type of the signature
|
||||
var signature = getContextualSignature(<Expression><Node>func);
|
||||
var signature = getContextualSignatureForFunctionLikeDeclaration(<FunctionExpression>func);
|
||||
if (signature) {
|
||||
return getReturnTypeOfSignature(signature);
|
||||
}
|
||||
@ -4951,12 +4950,21 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isFunctionExpressionOrArrowFunction(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
|
||||
}
|
||||
|
||||
function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature {
|
||||
// Only function expressions and arrow functions are contextually typed.
|
||||
return isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(<FunctionExpression>node) : undefined;
|
||||
}
|
||||
|
||||
// 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
|
||||
// all identical ignoring their return type, the result is same signature but with return type as
|
||||
// union type of return types from these signatures
|
||||
function getContextualSignature(node: Expression): Signature {
|
||||
function getContextualSignature(node: FunctionExpression): Signature {
|
||||
var type = getContextualType(node);
|
||||
if (!type) {
|
||||
return undefined;
|
||||
@ -5990,7 +5998,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type {
|
||||
var contextualSignature = getContextualSignature(<Expression><Node>func);
|
||||
var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
|
||||
if (func.body.kind !== SyntaxKind.FunctionBlock) {
|
||||
var unwidenedType = checkAndMarkExpression(<Expression>func.body, contextualMapper);
|
||||
var widenedType = getWidenedType(unwidenedType);
|
||||
|
||||
@ -445,11 +445,11 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getContainingFunction(node: Node): SignatureDeclaration {
|
||||
export function getContainingFunction(node: Node): FunctionLikeDeclaration {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node || isAnyFunction(node)) {
|
||||
return <SignatureDeclaration>node;
|
||||
return <FunctionLikeDeclaration>node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1936,8 +1936,8 @@ module ts {
|
||||
});
|
||||
}
|
||||
|
||||
function parseIndexSignatureMember(fullStart: number, modifiers: ModifiersArray): SignatureDeclaration {
|
||||
var node = <SignatureDeclaration>createNode(SyntaxKind.IndexSignature, fullStart);
|
||||
function parseIndexSignatureDeclaration(fullStart: number, modifiers: ModifiersArray): IndexSignatureDeclaration {
|
||||
var node = <IndexSignatureDeclaration>createNode(SyntaxKind.IndexSignature, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
@ -1994,7 +1994,7 @@ module ts {
|
||||
return parseSignatureMember(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
// Indexer or computed property
|
||||
return isIndexSignature() ? parseIndexSignatureMember(scanner.getStartPos(), /*modifiers:*/ undefined) : parsePropertyOrMethod();
|
||||
return isIndexSignature() ? parseIndexSignatureDeclaration(scanner.getStartPos(), /*modifiers:*/ undefined) : parsePropertyOrMethod();
|
||||
case SyntaxKind.NewKeyword:
|
||||
if (lookAhead(() => nextToken() === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken)) {
|
||||
return parseSignatureMember(SyntaxKind.ConstructSignature, SyntaxKind.ColonToken);
|
||||
@ -3779,7 +3779,7 @@ module ts {
|
||||
return parseConstructorDeclaration(fullStart, modifiers);
|
||||
}
|
||||
if (isIndexSignature()) {
|
||||
return parseIndexSignatureMember(fullStart, modifiers);
|
||||
return parseIndexSignatureDeclaration(fullStart, modifiers);
|
||||
}
|
||||
// It is very important that we check this *after* checking indexers because
|
||||
// the [ token can start an index signature or a computed property name
|
||||
|
||||
@ -354,7 +354,7 @@ module ts {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface SignatureDeclaration extends Declaration, ParsedSignature, ClassElement {
|
||||
export interface SignatureDeclaration extends Declaration, ParsedSignature {
|
||||
}
|
||||
|
||||
export interface VariableDeclaration extends Declaration {
|
||||
@ -383,6 +383,8 @@ module ts {
|
||||
* AccessorDeclaration
|
||||
*/
|
||||
export interface FunctionLikeDeclaration extends SignatureDeclaration {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
|
||||
asteriskToken?: Node;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
@ -396,14 +398,18 @@ module ts {
|
||||
body?: Block;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends Declaration, ParsedSignature, ClassElement {
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
|
||||
body?: Block;
|
||||
}
|
||||
|
||||
export interface AccessorDeclaration extends FunctionLikeDeclaration {
|
||||
export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement {
|
||||
body?: Block;
|
||||
}
|
||||
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement {
|
||||
_indexSignatureDeclarationBrand: any;
|
||||
}
|
||||
|
||||
export interface TypeNode extends Node { }
|
||||
|
||||
export interface TypeReferenceNode extends TypeNode {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user