Make isJavascript parameters required

This is a bit wordy, but will probably prevent bugs similar to #18254 in
the future.
This commit is contained in:
Nathan Shively-Sanders
2017-09-13 10:44:11 -07:00
parent 014f7ba828
commit a1d1a2219b
2 changed files with 18 additions and 13 deletions

View File

@@ -6361,7 +6361,7 @@ namespace ts {
* @param typeParameters The requested type parameters.
* @param minTypeArgumentCount The minimum number of required type arguments.
*/
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScript?: boolean) {
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScript: boolean) {
const numTypeParameters = length(typeParameters);
if (numTypeParameters) {
const numTypeArguments = length(typeArguments);
@@ -6622,7 +6622,7 @@ namespace ts {
return anyType;
}
function getSignatureInstantiation(signature: Signature, typeArguments: Type[], isJavascript?: boolean): Signature {
function getSignatureInstantiation(signature: Signature, typeArguments: Type[], isJavascript: boolean): Signature {
typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript);
const instantiations = signature.instantiations || (signature.instantiations = createMap<Signature>());
const id = getTypeListId(typeArguments);
@@ -6661,7 +6661,10 @@ namespace ts {
// where different generations of the same type parameter are in scope). This leads to a lot of new type
// identities, and potentially a lot of work comparing those identities, so here we create an instantiation
// that uses the original type identities for all unconstrained type parameters.
return getSignatureInstantiation(signature, map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp));
return getSignatureInstantiation(
signature,
map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp),
isInJavaScriptFile(signature.declaration));
}
function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
@@ -6843,7 +6846,7 @@ namespace ts {
const id = getTypeListId(typeArguments);
let instantiation = links.instantiations.get(id);
if (!instantiation) {
links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters)))));
links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJavaScriptFile(symbol.valueDeclaration)))));
}
return instantiation;
}
@@ -13999,8 +14002,9 @@ namespace ts {
const instantiatedSignatures = [];
for (const signature of signatures) {
if (signature.typeParameters) {
const typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0);
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments));
const isJavascript = isInJavaScriptFile(node);
const typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript);
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
}
else {
instantiatedSignatures.push(signature);
@@ -15257,7 +15261,7 @@ namespace ts {
if (!contextualMapper) {
inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
}
return getSignatureInstantiation(signature, getInferredTypes(context));
return getSignatureInstantiation(signature, getInferredTypes(context), isInJavaScriptFile(contextualSignature.declaration));
}
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: boolean[], context: InferenceContext): Type[] {
@@ -15292,7 +15296,7 @@ namespace ts {
// Above, the type of the 'value' parameter is inferred to be 'A'.
const contextualSignature = getSingleCallSignature(instantiatedType);
const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters)) :
getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters, isInJavaScriptFile(node))) :
instantiatedType;
const inferenceTargetType = getReturnTypeOfSignature(signature);
// Inferences made from return types have lower priority than all other inferences.
@@ -16008,8 +16012,9 @@ namespace ts {
candidate = originalCandidate;
if (candidate.typeParameters) {
let typeArgumentTypes: Type[];
const isJavascript = isInJavaScriptFile(candidate.declaration);
if (typeArguments) {
typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidate.typeParameters, getMinTypeArgumentCount(candidate.typeParameters));
typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidate.typeParameters, getMinTypeArgumentCount(candidate.typeParameters), isJavascript);
if (!checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)) {
candidateForTypeArgumentError = originalCandidate;
break;
@@ -16018,7 +16023,7 @@ namespace ts {
else {
typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
}
candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript);
}
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
candidateForArgumentError = candidate;
@@ -18782,7 +18787,7 @@ namespace ts {
const constraint = getConstraintOfTypeParameter(typeParameters[i]);
if (constraint) {
if (!typeArguments) {
typeArguments = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount);
typeArguments = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, isInJavaScriptFile(typeArgumentNodes[i]));
mapper = createTypeMapper(typeParameters, typeArguments);
}
const typeArgument = typeArguments[i];

View File

@@ -1325,11 +1325,11 @@ namespace ts {
return isInJavaScriptFile(file);
}
export function isInJavaScriptFile(node: Node): boolean {
export function isInJavaScriptFile(node: Node | undefined): boolean {
return node && !!(node.flags & NodeFlags.JavaScriptFile);
}
export function isInJSDoc(node: Node): boolean {
export function isInJSDoc(node: Node | undefined): boolean {
return node && !!(node.flags & NodeFlags.JSDoc);
}