Move type predicate checking to checkTypePredicate

Also remove now-unused "Type predicate is only allowed as a return type"
diagnostic.
This commit is contained in:
Nathan Shively-Sanders 2015-12-08 09:36:46 -08:00
parent 1b63040d36
commit 47d267cdde
2 changed files with 60 additions and 74 deletions

View File

@ -10985,7 +10985,61 @@ namespace ts {
return -1;
}
function isInLegalTypePredicatePosition(node: Node): boolean {
function checkTypePredicate(node: TypePredicateNode) {
const parent = getTypePredicateParent(node);
if (!parent) {
return;
}
const typePredicate = getSignatureFromDeclaration(parent).typePredicate;
if (typePredicate.parameterIndex >= 0) {
if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
error(node.parameterName,
Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
}
else {
checkTypeAssignableTo(typePredicate.type,
getTypeOfNode(parent.parameters[typePredicate.parameterIndex]),
node.type);
}
}
else if (node.parameterName) {
let hasReportedError = false;
for (var param of parent.parameters) {
if (hasReportedError) {
break;
}
if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
param.name.kind === SyntaxKind.ArrayBindingPattern) {
(function checkBindingPattern(pattern: BindingPattern) {
for (const element of pattern.elements) {
if (element.name.kind === SyntaxKind.Identifier &&
(<Identifier>element.name).text === typePredicate.parameterName) {
error(node.parameterName,
Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
typePredicate.parameterName);
hasReportedError = true;
break;
}
else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
element.name.kind === SyntaxKind.ObjectBindingPattern) {
checkBindingPattern(<BindingPattern>element.name);
}
}
})(<BindingPattern>param.name);
}
}
if (!hasReportedError) {
error(node.parameterName,
Diagnostics.Cannot_find_parameter_0,
typePredicate.parameterName);
}
}
}
function getTypePredicateParent(node: Node): SignatureDeclaration {
switch (node.parent.kind) {
case SyntaxKind.ArrowFunction:
case SyntaxKind.CallSignature:
@ -10994,9 +11048,11 @@ namespace ts {
case SyntaxKind.FunctionType:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return node === (<SignatureDeclaration>node.parent).type;
const parent = <SignatureDeclaration>node.parent;
if (node === parent.type) {
return parent;
}
}
return false;
}
function checkSignatureDeclaration(node: SignatureDeclaration) {
@ -11015,67 +11071,7 @@ namespace ts {
forEach(node.parameters, checkParameter);
if (node.type) {
if (node.type.kind === SyntaxKind.TypePredicate) {
const typePredicate = getSignatureFromDeclaration(node).typePredicate;
const typePredicateNode = <TypePredicateNode>node.type;
if (isInLegalTypePredicatePosition(typePredicateNode)) {
if (typePredicate.parameterIndex >= 0) {
if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) {
error(typePredicateNode.parameterName,
Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
}
else {
checkTypeAssignableTo(typePredicate.type,
getTypeOfNode(node.parameters[typePredicate.parameterIndex]),
typePredicateNode.type);
}
}
else if (typePredicateNode.parameterName) {
let hasReportedError = false;
for (var param of node.parameters) {
if (hasReportedError) {
break;
}
if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
param.name.kind === SyntaxKind.ArrayBindingPattern) {
(function checkBindingPattern(pattern: BindingPattern) {
for (const element of pattern.elements) {
if (element.name.kind === SyntaxKind.Identifier &&
(<Identifier>element.name).text === typePredicate.parameterName) {
error(typePredicateNode.parameterName,
Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
typePredicate.parameterName);
hasReportedError = true;
break;
}
else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
element.name.kind === SyntaxKind.ObjectBindingPattern) {
checkBindingPattern(<BindingPattern>element.name);
}
}
})(<BindingPattern>param.name);
}
}
if (!hasReportedError) {
error(typePredicateNode.parameterName,
Diagnostics.Cannot_find_parameter_0,
typePredicate.parameterName);
}
}
}
else {
error(typePredicateNode,
Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
}
}
else {
checkSourceElement(node.type);
}
}
checkSourceElement(node.type);
if (produceDiagnostics) {
checkCollisionWithArgumentsInGeneratedCode(node);
@ -14217,12 +14213,6 @@ namespace ts {
}
}
function checkTypePredicate(node: TypePredicateNode) {
if (!isInLegalTypePredicatePosition(node)) {
error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
}
}
function checkSourceElement(node: Node): void {
if (!node) {
return;

View File

@ -711,10 +711,6 @@
"category": "Error",
"code": 1227
},
"A type predicate is only allowed in return type position for functions and methods.": {
"category": "Error",
"code": 1228
},
"A type predicate cannot reference a rest parameter.": {
"category": "Error",
"code": 1229