-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,8 +97,8 @@ module ts { | |
let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); | ||
let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); | ||
|
||
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); | ||
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); | ||
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false); | ||
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
let globals: SymbolTable = {}; | ||
|
||
|
@@ -2766,7 +2766,7 @@ module ts { | |
|
||
function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { | ||
if (!(<InterfaceTypeWithDeclaredMembers>type).declaredProperties) { | ||
var symbol = type.symbol; | ||
let symbol = type.symbol; | ||
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(symbol.members); | ||
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); | ||
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); | ||
|
@@ -2776,7 +2776,7 @@ module ts { | |
return <InterfaceTypeWithDeclaredMembers>type; | ||
} | ||
|
||
function resolveClassOrInterfaceMembers(type: InterfaceType): void { | ||
function resolveClassOrInterfaceMembers(type: InterfaceType) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
let target = resolveDeclaredMembers(type); | ||
let members = target.symbol.members; | ||
let callSignatures = target.declaredCallSignatures; | ||
|
@@ -2817,20 +2817,21 @@ module ts { | |
} | ||
|
||
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], | ||
resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { | ||
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { | ||
let sig = new Signature(checker); | ||
sig.declaration = declaration; | ||
sig.typeParameters = typeParameters; | ||
sig.parameters = parameters; | ||
sig.resolvedReturnType = resolvedReturnType; | ||
sig.typePredicate = typePredicate; | ||
sig.minArgumentCount = minArgumentCount; | ||
sig.hasRestParameter = hasRestParameter; | ||
sig.hasStringLiterals = hasStringLiterals; | ||
return sig; | ||
} | ||
|
||
function cloneSignature(sig: Signature): Signature { | ||
return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, | ||
return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate, | ||
sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); | ||
} | ||
|
||
|
@@ -2847,7 +2848,7 @@ module ts { | |
return signature; | ||
}); | ||
} | ||
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; | ||
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)]; | ||
} | ||
|
||
function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable { | ||
|
@@ -3219,7 +3220,24 @@ module ts { | |
} | ||
|
||
let returnType: Type; | ||
if (classType) { | ||
let typePredicate: TypePredicate; | ||
if (declaration.typePredicate) { | ||
returnType = booleanType; | ||
let typePredicateNode = declaration.typePredicate; | ||
let links = getNodeLinks(typePredicateNode); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
if (links.typePredicateParameterIndex === undefined) { | ||
links.typePredicateParameterIndex = getTypePredicateParameterIndex(declaration.parameters, typePredicateNode.parameterName); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
if (!links.typeFromTypePredicate) { | ||
links.typeFromTypePredicate = getTypeFromTypeNode(declaration.typePredicate.type); | ||
} | ||
typePredicate = { | ||
parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined, | ||
parameterIndex: typePredicateNode.parameterName ? links.typePredicateParameterIndex : undefined, | ||
type: links.typeFromTypePredicate | ||
This comment has been minimized.
Sorry, something went wrong. |
||
}; | ||
} | ||
else if (classType) { | ||
returnType = classType; | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
else if (declaration.type) { | ||
|
@@ -3238,7 +3256,7 @@ module ts { | |
} | ||
} | ||
|
||
links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, | ||
links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, | ||
minArgumentCount, hasRestParameters(declaration), hasStringLiterals); | ||
} | ||
return links.resolvedSignature; | ||
|
@@ -3944,9 +3962,13 @@ module ts { | |
freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter); | ||
mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); | ||
} | ||
if (signature.typePredicate) { | ||
signature.typePredicate.type = instantiateType(signature.typePredicate.type, mapper); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
let result = createSignature(signature.declaration, freshTypeParameters, | ||
instantiateList(signature.parameters, mapper, instantiateSymbol), | ||
signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined, | ||
signature.typePredicate, | ||
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); | ||
result.target = signature; | ||
result.mapper = mapper; | ||
|
@@ -4614,6 +4636,43 @@ module ts { | |
} | ||
result &= related; | ||
} | ||
|
||
if (source.typePredicate && target.typePredicate) { | ||
if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex || | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
tinganho
Author
Owner
|
||
source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { | ||
|
||
if (reportErrors) { | ||
let sourceParamText = source.typePredicate.parameterName; | ||
let targetParamText = target.typePredicate.parameterName; | ||
let sourceTypeText = typeToString(source.typePredicate.type); | ||
let targetTypeText = typeToString(target.typePredicate.type); | ||
|
||
if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex) { | ||
reportError(Diagnostics.Parameter_index_from_0_does_not_match_the_parameter_index_from_1, | ||
sourceParamText, | ||
targetParamText); | ||
} | ||
if (source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, | ||
sourceTypeText, | ||
targetTypeText); | ||
} | ||
|
||
reportError(Diagnostics.Type_guard_annotation_0_is_not_assignable_to_1, | ||
`${sourceParamText} is ${sourceTypeText}`, | ||
`${targetParamText} is ${targetTypeText}`); | ||
} | ||
|
||
return Ternary.False; | ||
} | ||
} | ||
else if (!source.typePredicate && target.typePredicate) { | ||
if (reportErrors) { | ||
reportError(Diagnostics.A_non_type_guard_function_is_not_assignable_to_a_type_guard_function); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
return Ternary.False; | ||
} | ||
|
||
let t = getReturnTypeOfSignature(target); | ||
if (t === voidType) return result; | ||
let s = getReturnTypeOfSignature(source); | ||
|
@@ -5146,6 +5205,13 @@ module ts { | |
|
||
function inferFromSignature(source: Signature, target: Signature) { | ||
forEachMatchingParameterType(source, target, inferFromTypes); | ||
if (source.typePredicate && | ||
target.typePredicate && | ||
target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
|
||
inferFromTypes(source.typePredicate.type, target.typePredicate.type); | ||
return; | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); | ||
} | ||
|
||
|
@@ -5527,7 +5593,7 @@ module ts { | |
let targetType: Type; | ||
let prototypeProperty = getPropertyOfType(rightType, "prototype"); | ||
if (prototypeProperty) { | ||
// Target type is type of the protoype property | ||
// Target type is type of the prototype property | ||
let prototypePropertyType = getTypeOfSymbol(prototypeProperty); | ||
if (prototypePropertyType !== anyType) { | ||
targetType = prototypePropertyType; | ||
|
@@ -5543,7 +5609,6 @@ module ts { | |
else if (rightType.flags & TypeFlags.Anonymous) { | ||
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct); | ||
} | ||
|
||
if (constructSignatures && constructSignatures.length) { | ||
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))); | ||
} | ||
|
@@ -5563,10 +5628,38 @@ module ts { | |
return type; | ||
} | ||
|
||
function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type { | ||
if (type.flags & TypeFlags.Any) { | ||
return type; | ||
} | ||
let signature = getResolvedSignature(expr); | ||
if (!assumeTrue) { | ||
if (type.flags & TypeFlags.Union && signature.typePredicate) { | ||
return getUnionType(filter((<UnionType>type).types, t => !isTypeSubtypeOf(t, signature.typePredicate.type))); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
return type; | ||
} | ||
if (signature.typePredicate) { | ||
if (expr.arguments && expr.arguments[signature.typePredicate.parameterIndex]) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
tinganho
Author
Owner
|
||
if (getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { | ||
if (isTypeSubtypeOf(signature.typePredicate.type, type)) { | ||
return signature.typePredicate.type; | ||
} | ||
if (type.flags & TypeFlags.Union) { | ||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, signature.typePredicate.type))); | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
tinganho
Author
Owner
|
||
} | ||
} | ||
} | ||
return type; | ||
} | ||
|
||
// Narrow the given type based on the given expression having the assumed boolean value. The returned type | ||
// will be a subtype or the same type as the argument. | ||
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type { | ||
switch (expr.kind) { | ||
case SyntaxKind.CallExpression: | ||
return narrowTypeByTypePredicate(type, <CallExpression>expr, assumeTrue); | ||
case SyntaxKind.ParenthesizedExpression: | ||
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue); | ||
case SyntaxKind.BinaryExpression: | ||
|
@@ -8468,6 +8561,20 @@ module ts { | |
node.kind === SyntaxKind.FunctionExpression; | ||
} | ||
|
||
function getTypePredicateParameterIndex(parameterList: NodeArray<ParameterDeclaration>, parameter: Identifier): number { | ||
let index = -1; | ||
if (parameterList) { | ||
for (let i = 0; i < parameterList.length; i++) { | ||
let param = parameterList[i]; | ||
if (param.name.kind === SyntaxKind.Identifier && | ||
(<Identifier>param.name).text === parameter.text) { | ||
|
||
return i; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function checkSignatureDeclaration(node: SignatureDeclaration) { | ||
// Grammar checking | ||
if (node.kind === SyntaxKind.IndexSignature) { | ||
|
@@ -8488,6 +8595,27 @@ module ts { | |
checkSourceElement(node.type); | ||
} | ||
|
||
if (node.typePredicate) { | ||
let links = getNodeLinks(node.typePredicate); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
if (links.typePredicateParameterIndex === undefined) { | ||
links.typePredicateParameterIndex = getTypePredicateParameterIndex(node.parameters, node.typePredicate.parameterName); | ||
} | ||
if (!links.typeFromTypePredicate) { | ||
links.typeFromTypePredicate = getTypeFromTypeNode(node.typePredicate.type); | ||
} | ||
if (links.typePredicateParameterIndex >= 0) { | ||
checkTypeAssignableTo( | ||
links.typeFromTypePredicate, | ||
getTypeAtLocation(node.parameters[links.typePredicateParameterIndex]), | ||
node.typePredicate.type); | ||
} | ||
else if(node.typePredicate.parameterName) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
error(node.typePredicate.parameterName, | ||
Diagnostics.Cannot_find_parameter_0, | ||
node.typePredicate.parameterName.text); | ||
} | ||
} | ||
|
||
if (produceDiagnostics) { | ||
checkCollisionWithArgumentsInGeneratedCode(node); | ||
if (compilerOptions.noImplicitAny && !node.type) { | ||
|
@@ -10047,9 +10175,6 @@ module ts { | |
if (node.expression) { | ||
let func = getContainingFunction(node); | ||
if (func) { | ||
let returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); | ||
let exprType = checkExpressionCached(node.expression); | ||
|
||
if (func.asteriskToken) { | ||
// A generator does not need its return expressions checked against its return type. | ||
// Instead, the yield expressions are checked against the element type. | ||
|
@@ -10058,6 +10183,13 @@ module ts { | |
return; | ||
} | ||
|
||
let signature = getSignatureFromDeclaration(func); | ||
let exprType = checkExpressionCached(node.expression); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
if (signature.typePredicate && exprType !== booleanType) { | ||
error(node.expression, Diagnostics.A_type_guard_function_can_only_return_a_boolean); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
|
||
} | ||
let returnType = getReturnTypeOfSignature(signature); | ||
|
||
if (func.kind === SyntaxKind.SetAccessor) { | ||
error(node.expression, Diagnostics.Setters_cannot_return_a_value); | ||
} | ||
|
Oh gosh, these signatures are too long :(